www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Delegates and C++ FFI lifetimes

reply IGotD- <nise nise.com> writes:
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.
Jul 02 2020
parent Kagamin <spam here.lot> writes:
You can store the delegate in an array and invoke it by index.
Jul 03 2020