wrapping a C style delegate

Nicholas Wilson via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Aug 25 17:49:20 PDT 2017


On Saturday, 26 August 2017 at 00:27:47 UTC, Ali Çehreli wrote:
> I think you need a variation of intermediateCallback() below. I 
> passed the address of the delegate as userData but you can 
> construct any context that contains everything that you need 
> (e.g. the address of ms).
>
> import std.stdio;
>
> // The C struct
> struct Struct {
>     int i;
> }
>
> // Some C type
> enum ErrorEnum {
>     zero
> }
>
> // Some C function taking a callback
> ErrorEnum SomeAPIaddCallback(Struct* s, void function(Struct*, 
> ErrorEnum status, void *userData) callback, void *userData, 
> uint flags) {
>     writeln("SomeAPIaddCallback called for object ", s);
>     writeln("Calling the callback...");
>     callback(s, ErrorEnum.zero, userData);
>     return ErrorEnum.zero;
> }
>
> // The callback to pass to the C function
> void intermediateCallback(Struct * s, ErrorEnum status, void 
> *userData) {
>     writeln("intermediateCallback called");
>     auto cb = cast(void delegate(ErrorEnum)*)userData;
>     (*cb)(status);
> }
>
> // The D wrapper always passes intermediateCallback to the C 
> function
> struct MyStruct {
>     Struct * s;
>     void addCallback(void delegate(ErrorEnum ee) callback) {
>         SomeAPIaddCallback(s, &intermediateCallback, &callback, 
> 0);
>     }
> }
>
> void main() {
>     auto s = Struct(42);
>     auto ms = MyStruct(&s);
>     ms.addCallback((ErrorEnum ee) {
>             writefln("The callback is called with %s for %s", 
> ee, ms.s);
>     });
> }
>
> Ali

I was thinking of something along those lines: but what about the 
lifetime of the passed delegate (the address of a local 
variable)? How can I ensure that it won't segfault when callback 
goes out of scope?
I could new it with the GC but
a) I'd rather have the wrapper be @nogc and
b) i'd have to hold a reference to it or pin it because 
SomeAPIaddCallback will be in a driver somewhere and wouldn't get 
scanned by the GC.



More information about the Digitalmars-d-learn mailing list