Using delegates for C callbacks.
Leandro Lucarella
llucax at gmail.com
Fri Feb 1 16:09:34 PST 2008
Kirk McDonald, el 1 de febrero a las 14:23 me escribiste:
[snip]
> Try something like this:
>
> extern(C) void f(void function(void*) fn, void* closure) {
> fn(closure);
> }
>
> class C {
> void foo(int i) {}
> }
>
> struct Closure {
> C self;
> int arg;
> }
>
> // It is possible to do some template trickery in order to
> // generalize this thunk for any function signature and any
> // class, but it is simpler to get the point across with a
> // concrete example.
> extern(C) void thunk(alias Fn)(void* _closure) {
> void delegate(int) dg;
> Closure* closure = cast(Closure*)_closure;
> dg.funcptr = &Fn;
> dg.ptr = cast(void*)(closure.self);
> dg(closure.arg);
> }
>
> void main() {
> C c = new C;
> auto closure = new Closure;
> closure.self = c;
> closure.arg = 20;
> // Note that we're passing the function C.foo and not
> // the method c.foo.
> thunk!(C.foo)(closure);
> f(&thunk!(C.foo), closure);
> }
Thanks, Kirk! The trick about passing the C.foo function instead of the
c.foo method was defenely the trick. I adapted your example to what I
needed, which is simpler because I don't need the Closure wrapper, so the
code is more general without extra complexity:
import std.stdio;
extern(C) void f(void function(void*) fn, void* closure) {
fn(closure);
}
class C {
int x;
void foo() {
writefln("foo: ", x);
}
}
// It is possible to do some template trickery in order to
// generalize this thunk for any function signature and any
// class, but it is simpler to get the point across with a
// concrete example.
extern(C) void thunk(alias Fn)(void* closure) {
void delegate() dg;
dg.funcptr = &Fn;
dg.ptr = closure;
dg();
}
void main() {
C c = new C;
// Note that we're passing the function C.foo and
// not the method c.foo.
c.x = 1;
thunk!(C.foo)(cast (void*) c);
c.x = 2;
f(&thunk!(C.foo), cast (void*) c);
}
PS: Thanks BCS for the answer. I didn't try it either because I didn't
understand it and found it too twisted, I was looking for something
simpler :)
--
Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/
----------------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------------
Dentro de 30 aņos Argentina va a ser un gran supermercado con 15
changuitos, porque esa va a ser la cantidad de gente que va a poder
comprar algo.
-- Sidharta Wiki
More information about the Digitalmars-d-learn
mailing list