Running a delegate inside a C function
Denis Martinez via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Sat Jun 7 12:24:58 PDT 2014
I am trying to make a binding for the Jack Audio Connection Kit, which I figured would be a good exercise to start and hopefully to replace C++ for my long term audio work.
I am making good progress (complete C API covered), and currently I am hitting a brick wall where delegates are concerned, while making some proper idiomatic D wrapper classes.
Below I have copied some relevant fragments of code, with the debug messages.
I want to pass a delegate as callback to a C function which is designed to receive the usual (function, void*) arguments.
The delegate is passed to JackClient's process_callback method. Here I make a C function for the purpose of wrapping, which receives into (void*)arg the delegate pointer obtained by &dg. Later in the method I save the delegate in the instance to protect it form being collected.
The problem is, as the C function is being called back, it crashes.
The trace tells that inside it the delegate address is determined correctly, while dg.ptr and dg.funcptr are not.
Am I doing something wrong here?
This is the trace of the execution:
New jack_client with name: Toto
passed to jack_set_process_thread f=0x460950 arg=0x7fff8b32fa20
delegate with funcptr=0x451d40 ptr=null
Press a key to stop.
1. enter with arg=0x7fff8b32fa20
2. delegate with funcptr=0xa ptr=0x69e8c0
Error executing command run: Program exited with code -11
--- app.d
JackClient client = new JackClient;
client.open("Toto", jack_options_t.JackNoStartServer, null);
scope(exit) client.close();
writeln("New jack_client with name: " ~ client.get_name());
client.process_callback = delegate int(jack_nframes_t nframes) {
writefln("PROCESSING %d frames", nframes);
return 0;
};
--- jack/jack.d
alias JackProcessDelegate = int delegate(jack_nframes_t nframes);
class JackClient {
JackProcessDelegate process_callback_;
@property
void process_callback(JackProcessDelegate dg)
{
extern (C) JackProcessCallback f = function int(jack_nframes_t nframes, void *arg)
{
// return (*cast(JackProcessDelegate *)arg)(nframes);
int ret;
writefln("1. enter with arg=%#x", arg);
auto dg = cast(JackProcessDelegate *)arg;
writefln("2. delegate with funcptr=%#x ptr=%#x", dg.funcptr, dg.ptr);
ret = (*dg)(nframes);
writeln("3. end");
return ret;
};
writefln("passed to jack_set_process_thread f=%#x arg=%#x", f, &dg);
writefln(" delegate with funcptr=%#x ptr=%#x", dg.funcptr, dg.ptr);
int ret = jack_set_process_callback(handle_, f, &dg);
if (ret != 0) {
throw new JackError("jack_set_process_callback");
}
process_callback_ = dg;
}
}
More information about the Digitalmars-d-learn
mailing list