Using delegates for C callbacks.
Leandro Lucarella
llucax at gmail.com
Fri Feb 1 21:11:31 PST 2008
Leandro Lucarella, el 2 de febrero a las 02:17 me escribiste:
> Is this too wrong? I guess the casting from dg.funcptr to an extern (C)
> function is not (I don't know if D calling convention is warrantied to be
> the same as C, and I don't know if is warrantied that the first argument
> to a delegate is the context pointer), but I really want the generality
> and simplicity of this code, it makes no sense to need code more complex
> than that to do what I want to do.
Well, it was that wrong, it only worked with delegates without arguments.
I saw that the D calling conventions are defined in the D ABI
specification so they aren't always the same as the C calling conventions,
I guess.
I finally decided to go with this:
import std.stdio;
extern(C) void c_f(void function(int, void*) fn, int data, void* closure) {
fn(data, closure);
}
class C {
int x;
void foo(int data) {
writefln("C.foo: x=", x, ", data=", data);
}
}
struct Delegate
{
void delegate(int) dg;
}
extern (C) void thunk(int revents, void* data)
{
auto d = cast (Delegate*) data;
d.dg(revents);
}
void d_f(void delegate(int) dg, int data)
{
auto d = new Delegate;
d.dg = dg;
c_f(&thunk, data, d);
}
void main() {
void foo(int data) {
writefln("foo: data=", data);
}
C c = new C;
c.x = 1;
d_f(&foo, 10);
d_f(&c.foo, 5);
}
I'm not crazy about the heap allocation, but at least is simple, safe and
general. And the templated thunk version wont work either if I want the
API usage to be simple (with templates, users will be forced to pass the
function pointer, which can be calculated at compile-time, separated from
the context pointer, which is always a runtime value).
--
Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/
----------------------------------------------------------------------------
GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05)
----------------------------------------------------------------------------
JUGAR COMPULSIVAMENTE ES PERJUDICIAL PARA LA SALUD.
-- Casino de Mar del Plata
More information about the Digitalmars-d-learn
mailing list