This is the first time I try to use Racket's FFI. I would like to create an application that binds to libgit2
in order to manipulate GIT repositories.
The first thing I would need to do is to initialize a repository, as shown in the libgit2
documentation:
git_repository *repo = NULL;
int error = git_repository_init(&repo, "/tmp/…", false);
Getting the function call in Racket is simple enough:
(require ffi/unsafe
ffi/unsafe/define)
(define-ffi-definer define-libgit (ffi-lib "/opt/local/lib/libgit2.dylib"))
(define _git_repository-ptr (_cpointer/null 'git_repository))
(define-libgit git_repository_init (_fun _git_repository-ptr _string _bool -> _int))
But then trying to use the function does not work:
-> (define new_repo _git_repository-ptr)
-> (git_repository_init new_repo "/tmp/..." #f)
; git_repository->C: argument is not `git_repository' pointer
; argument: #<ctype>
; [,bt for context]
libgit2
does not offer a function to initialize the pointer, as shown in the Racket FFI documentation example.
Is this the correct way to define a nullable pointer and initialize it to NULL
?
git_repository
, on the other hand, is a struct
defined in the library. Am I supposed to use define-cstruct
on the Racket side to get it correctly? This can be cumbersome, since the struct
is defined in terms of other struct
s, with some levels of nesting. Are there any patterns to handle this situation?