pass a delegate to an API as a context pointer?

Kirk McDonald kirklin.mcdonald at gmail.com
Mon Jul 2 16:36:19 PDT 2007


Russell Lewis wrote:
> teo wrote:
> 
>> Hi *, is it possible to pass a delegate to an API function which takes 
>> a pointer to a callback function and a context pointer? The code 
>> bellow describes what I'm trying to achieve.
>>
>> // C-Library
>> typedef void (*callback)(void *context);
>> void xyz(callback handler, void *context);
>>
>> // D-Program
>> alias void function(void *context) callback;
>> extern(C) void xyz(callback handler, void *context);
>> alias int delegate() foo;
> 
> 
> Your code below shouldn't work because void* is 4 bytes (a single 
> pointer) whereas a delegate is 8 bytes (two pointers).  But you can do 
> this:
> 
> 
> struct CallbackBouncer
> {
>   int delegate() whatToCall;
> }
> extern(C) void CallbackBouncer_callback(void *ptr)
> {
>   CallbackBouncer *cb = cast(CallbackBouncer*)ptr;
>   ptr.whatToCall();
> }
> 
> void main()
> {
>   A a = new A();
>   CallbackBouncer *cb = new CallbackBouncer[1];
>   cb.whatToCall = &a.abc;
>   xyz( CallbackBouncer_callback, cast(void*)cb);
> }
> 
> // A quibble: notice that the 'int' return code in
> // A.abc is being ignored b/c C expects a return code
> // of void.
> 

There is a serious problem with this. The garbage collector will not 
scan the C library for references. As far as it is concerned, that 
struct on the heap will have no references to it (assuming your program 
is more interesting than a single main() function, and this callback is 
being assigned in some function that returns), and it might be 
collected. Furthermore, if that delegate holds the only reference to 
that 'A' instance, it might be collected, too.

You'll need to somehow keep a reference to that struct locally (that is, 
within your D code).

Also, a minor quibble: You have to use & when getting a pointer to a 
function in D.

-- 
Kirk McDonald
http://kirkmcdonald.blogspot.com
Pyd: Connecting D and Python
http://pyd.dsource.org



More information about the Digitalmars-d mailing list