pass a delegate to an API as a context pointer?

Russell Lewis webmaster at villagersonline.com
Mon Jul 2 16:16:45 PDT 2007


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.



> class A
> {
> 	int abc() { return 1; }
> }
> class B
> {
> 	static void handler(void *context)
> 	{
> 		foo f = cast(foo)context;
> 		int i = f();	// call A.abc();
> 	}
> 	void test(foo f)
> 	{
> 		xyz(cast(callback)handler, cast(void*)f);
> 	}
> }
> void main()
> {
> 	A a = new A();
> 	B b = new B();
> 	b.test(&a.abc);
> }



More information about the Digitalmars-d mailing list