The idea was to have the `OdbBackend` constructor be the point at which
you hand your C pointer to a `git_odb_backend` and then use the API as
normal, with Go objects. There is no need to hide the code that
associates an odb to a repo or for the library to use callbacks. If we
have something like this in `odb.go`

```go
type OdbBackend struct {
	ptr *C.git_odb_backend
}

func NewOdbBackendFromC(ptr *C.git_odb_backend) (*OdbBackend, error) {
	backend = &OdbBackend{ptr}

	return backend
}
```

then `Odb.AddBackend()` can take in a `*OdbBackend` and access its `ptr`
field, as we do with any other object.

The app code would look something like this (assuming you keep to the
library's convention on error codes):

``go
var cbackend *C.git_odb_backend
ret := C.my_fancy_odb_backend_new(&cbackend, user, pass, cookie,
biscuit)
// handle error
backend := git.NewOdbBackendFromC(cbackend)
odb = git.NewOdb()
err := odb.AddBackend(backend, 42)
``

and then you're just using the libgit2 API without needing to wrap
everything in a closure.

   cmn

On Thu, 2013-12-19 at 07:59 -0800, Aidan Nulman wrote:
> > @@ -17,6 +17,31 @@ type Odb struct {
> >  	ptr *C.git_odb
> >  }
> >  
> > +// OdbBackends need public Ptrs: client apps init the backend
> > +type OdbBackend struct {
> > +  Ptr *C.git_odb_backend
> 
> Hmmm... backend constructors are C functions that need git_odb_backend **out, and will be different from one client to the next. I can only think of two ways to achieve this...
> 
> Sharing the pointer (whether through public variable or a getter), e.g.:
> ```go
> /* GIT2GO */
> type OdbBackend struct {
> 	Ptr *C.git_odb_backend
> }
> 
> /* CLIENT */
> // ...
> 
> cpath := C.CString(kyotoPath)
> defer C.free(unsafe.Pointer(cpath))
> 
> // handoff to c, convert C.int to int for error check
> ret := C.git_odb_backend_kyoto(&backend.Ptr, cpath)
> if ret < 0 {
> 	err = git.LastError()
> }
> 
> // ...
> ```
> 
> Or passing an abstract function, e.g.:
> ```go
> /* GIT2GO */
> type OdbBackend struct {
> 	ptr *C.git_odb_backend
> }
> type BackendConstructor func(**C.git_odb_backend) int
> 
> func (v *Odb) AddBackend(constructor BackendConstructor , priority int) (err error) {
> 	// ...
> }
> 
> /* CLIENT */
> // ...
> 
> constructorFunc := func(backend **C.git_odb_backend) (ret int) {
> 	cpath := C.CString(kyotoPath)
> 	defer C.free(unsafe.Pointer(cpath))
> 
> 	// handoff to c, convert C.int to int for error check
> 	cret := C.git_odb_backend_kyoto(backend, cpath)
> 	ret = int(cret)
> }
> odb.AddBackend(constructorFunc, 1)
> 
> // ...
> ```
> 
> I considered writing an interface too, but I could not see how to avoid sharing the pointer as in example 1.
> 
> If neither of the above are satisfactory, do you have any advice/resources you could recommend before I push the next commit?
> 
> ---
> Reply to this email directly or view it on GitHub:
> https://github.com/libgit2/git2go/pull/48/files#r8473311