Reputation: 2991
Since days im trying to call some D code from C++ (with an class/interface defined for C++ and D).
the D code
module BufferCppBinding;
extern (C++) void *createBufferCppBinding() {
BufferCppBinding ptr = new BufferCppBinding();
return cast(void*)ptr;
}
extern (C++) interface BufferCppBindingInterface {
void construct();
// ...
}
class BufferCppBinding : BufferCppBindingInterface {
public Buffer thisPtr;
public extern (C++) void construct() {
// doesn't do anything
}
}
the C++ code for declaring the type to C++ land:
class BufferCppBinding {
public:
virtual void construct();
};
for the initialisation of the D runtime i wrote a small function in D which does in D land:
extern (C++) void initDRuntime() nothrow{
try
{
Runtime.initialize();
//result = myWinMain(hInstance, hPrevInstance, lpCmdLine, iCmdShow);
//Runtime.terminate(&exceptionHandler);
}
catch (Throwable o)
{
//MessageBox(null, o.toString().toUTF16z, "Error", MB_OK | MB_ICONEXCLAMATION);
//result = 0;
}
}
usage (C++):
BufferCppBinding *vertexBuffer = reinterpret_cast<BufferCppBinding*>(createBufferCppBinding());
// here happens the crash
vertexBuffer->construct();
I am compiling the code with g++ 5.2 and ldc2 and linking it with ldc2.
I just get a SIGSEGV.
Upvotes: 4
Views: 168
Reputation: 1412
Returning pointers to C++ that point to the GC heap is a bad idea - use malloc
/emplace
(or std.experimental.allocator.make) instead and call
freeon the C++ side. That won't run destructors though, so maybe you want to expose a D function that calls
destroy` as well.
BTW, no need to return void*
and cast back - just return BufferCppBindingInterface
from createBufferCppBinding
.
Upvotes: 2