On 22 Feb 2015, at 01:19, Nicolai Hess <nicolaihess@web.de> wrote:

2015-02-22 0:06 GMT+01:00 Max Leske <maxleske@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