On 25 January 2013 02:13, Stefan Marr <smalltalk@stefan-marr.de> wrote:
Hi:
I don't really understand how NativeBoostFFI handles pointers.
I have two functions like this:
self call: #(int git_repository_open(git_repository * * handle, char * path))
and
self call: #(int git_repository_head(git_reference * * refHandle, git_repository * repo))
They use a type mapping like this: #('git_repository' 'NBVoid' 'git_reference' 'NBVoid' )
So, nothing special going on here, just pointers to pointers, and pointers to opaque data structures.
Now, the call to the _open function is done with a `repoHandle := NBExternalHandle new`. This works, and I get the result value of the c lib inside my repoHandle.
However, if I want to use it in the _head call, I first have to convert it into a NBExternalAddress (`NBExternalAddress value: repoHandle value`).
Took me a while to figure out that passing in the repoHandle to _head does actually do the wrong thing. The _head function then gets the address of repoHandle instead of its value, which is wrong for my usecase.
However, just passing in `repoHandle value` results in some strange _nil_ error.
So, the main question is, why do I need to convert between Handle and Address?
For the library I am trying to use, that becomes a somehow recurring pattern:
| repo repoPath cb branches headHandle | repo := NBExternalHandle new. repoPath := NBExternalAddress fromString: '/Users/smarr/tmp/filetree'.
why not just pass the string?
LG2RepositoryH uniqueInstance repository_open: repo path: repoPath. repo := NBExternalAddress value: repo value. "<-- Why is this necessary?"
headHandle := NBExternalHandle new. LG2RepositoryH uniqueInstance repository_head: headHandle repo: repo.
^ (LG2RefsH uniqueInstance reference_name: (NBExternalAddress value: headHandle value)) "<-- Why is this necessary?" readString
yeah.. that double indirection is often source of confusion. but you can make a subclass of NBExternalObject , say 'GitReference' to be equal to 'git_reference *' and 'GitRepository' to 'git_repository *' like that, then in signature you need to rewrite to: self call: #(int git_repository_head(GitReference * refHandle, GitRepository repo)) this should work, because converter will push a pointer to the location where your handle value is stored (if with *) or push its value without.
Thanks Stefan
-- Stefan Marr Software Languages Lab Vrije Universiteit Brussel Pleinlaan 2 / B-1050 Brussels / Belgium http://soft.vub.ac.be/~smarr Phone: +32 2 629 2974 Fax: +32 2 629 3525
-- Best regards, Igor Stasenko.