> On 22 Feb 2015, at 01:19, Nicolai Hess <nicolaih...@web.de> wrote:
> 
> 2015-02-22 0:06 GMT+01:00 Max Leske <maxle...@gmail.com 
> <mailto:maxle...@gmail.com>>:
> Hi.
> 
> I have a situation with libgit2 where the function I need to call is a field 
> in a struct (the field gets populated with different functions with the same 
> signature depending on certain conditions).
> 
> I’m facing two problems now:
> 1. how do I define a function as the field type of an NBExternalStructure?
> 
> Athens creates a structure with callbacks as a surface plugin for the 
> bitblter (SQSurfaceDispatch).
> But this is a structur with functions (generated with NB) that are called 
> "from the outside"
>  
> 2. how can I call the function?
> 
> I don't know of any example in the image, where we are calling a function 
> defined in a struct.
> Maybe you can extend NBFFICallout to generate a call from a function spec + 
> function address
> 
> NBFFICallout>>#generateCall:module: does this, it generates a call from a 
> function spec and and
> address loockuped in a module, maybe you can do something similiar, but use 
> the function address from
> the structure isntead of calling nbGetSymbolAddress:module: 

I’ll give that a try, thanks.

> 
>  
> 
> I’ve tried using callbacks as field types. That works as far as I can access 
> the functions by pointer. But how would I then call that function?
> I’ve looked at NBNativeFunction and NBNativeFunctionGen but I can’t see how I 
> should use either of those to make a plain call.
> 
> Here’s a more precise description of my problem:
> 
> writepack := LG2GitOdbWritepackS new.
> … “initialize the struct externally”
> 
> “now call the function ‘commit’ and pass the arguments (this is how I imagine 
> it could work…)"
> writepack commit
>         value: writepack
>         value: anotherStruct.
> 
> 
> Needed struct fields:
> 
> backend:        git_odb_backend *
> append:                 int (*)(git_odb_writepack *, const void *, size_t, 
> git_transfer_progress *)
> commit:                 int (*)(git_odb_writepack *, git_transfer_progress *)
> free:                   void (*)(git_odb_writepack *)
> 
> 
> For what is this needed?  Do you want to write your own git backend?

No. I need to implement packing of loose objects to save space. libgit2 only 
does this for network transport. For this I need to work with the pack backend 
directly and the backend provides the function I need to call for finishing the 
write in the “commit” field of the struct. Of course, I know which function 
that will be since I’m working with one particular backend. But if I wanted to 
support multiple backends in the future it would be better to call the provided 
function instead of explicitly naming it.

> 
> I find this strange. I only know of two use cases for function pointers in a 
> structs.
> 1. to define the callbacks (like athens does it for the SQSurfaceDispatch). 
> But we only define the functions and don't call them.
> 2. a library defines a public api and delegates the implementation to 
> different backends, but structure and backend functions
>     are hidden. Users of the library don't call them.

Exactly. I’m dipping deeper here than one usually needs to.

Thanks Nicolai.

> 
> 
> 
>  
> 
> My current (ad hoc) struct fields:
> 
> fieldsDesc
>         ^#(
>         LG2GitOdbO backend;
>         LG2WritePackAppendCb append;
>         LG2WritePackCommitCb commit;
>         LG2WritePackFreeCb free;
>         )
> 
> 
> I’d even be happy if I have to implement a method on LG2GitOdbWritepackS for 
> every function call (e.g. “writepack commit: arg1 and: arg2”) but how would I 
> make the call?
> 
> Any ideas?
> Max
> 

Reply via email to