July 02, 2020
I have this runtime written in C++ that allows callbacks for various functionality. In C++ the callbacks are stored as a function pointer together with a void* that is passed as first argument. The void* can be a lot of things, for example the class pointer in C++. However, this is a bit limited for D and the question is if you can use the void* in order to store a pointer to a D delegate instead. A trampoline function just casts the void* to a delegate and you go from there.

Basically:

class TestClass
{
    void test() { writeln("test"); }
}

void Setup()
{
    auto t = new TestClass;
    MyCallbackSystem s = CreateCallbackSystem(); // C++ FFI interface
    s.SetCallback(&t.test); // SetCallback, a helper function for MyCallbackSystem
}

Where SetCallback accepts a D delegate. Now this delegate is completely scoped and will likely disappear when SetCallback ends. The void* where the delegate is stored is of course completely outside the knowledge of the GC. I assume this leads to that the C++ runtime will read an invalid pointer.

The question how can you best solve this so that the delegates lives as long as the object (s) associated with SetCallback. Can you actually dynamically in D allocate a delegate? I've never seen such idiom other than this thread

https://forum.dlang.org/thread/20080201213313.GB9684@homero.springfield.home

where the workaround seems to be having a delegate in a struct.



July 03, 2020
You can store the delegate in an array and invoke it by index.