Forum Navigation
DLL woes
Posted: 11/05/08 13:21:30Hi all, not sure if this is the right forum, but well. I am playing around with an XML parser that builds a list of DWT widgets and then calls the user code, that is packed in a DLL, because that allows for easy binding of strings to program symbols. Here I encounter the problem when passing objects to functions in the DLL. The simplest test case I could produce boils down to this:
myclasses.d:
module myclasses; class base { char[] toString(){ return "I am base"; } } class c1: base { char[] toString(){ return "I am c1";} } class c2: base { char[] toString(){ return "I am c2";} }mymain.d:
import tango.sys.SharedLib; import myclasses; void main(){ base[] instances; // populate instances instances.length=3; instances[0] = new base; instances[1] = new c1; instances[2] = new c2; // no problem assert( cast(c1) instances[1] !is null); assert( cast(c2) instances[2] !is null); SharedLib lib = SharedLib.load(`mydll.dll`); assert( lib !is null); extern(C) void function(base[]) my_c_check; void* ptr; void** point; ptr = lib.getSymbol("my_c_check"); point = cast(void** ) &my_c_check; *point = ptr; my_c_check( instances ); }and, finally, mydll.d:
import myclasses; import tango.sys.win32.Types; import tango.util.log.Trace; // The core DLL init code, taken from tango wiki. extern (C) bool rt_init( void delegate( Exception ) dg = null ); extern (C) bool rt_term( void delegate( Exception ) dg = null ); HINSTANCE g_hInst; extern (Windows) BOOL DllMain(HINSTANCE hInstance, ULONG ulReason, LPVOID pvReserved){ switch (ulReason){ case DLL_PROCESS_ATTACH: rt_init(); break; case DLL_PROCESS_DETACH: rt_term(); break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: // Multiple threads not supported yet return false; } g_hInst=hInstance; return true; } // End of core DLL Init extern(C) int my_c_check( base[] instances){ Trace.formatln("into my_c_check"); assert( instances.length ==3 ); Trace.formatln("length check OK"); assert( instances[0] !is null); assert( instances[1] !is null); assert( instances[2] !is null); Trace.formatln("instances check OK"); Trace.formatln("instances[0] says: {}", instances[0].toString() ); Trace.formatln("instances[1] says: {}", instances[1].toString() ); Trace.formatln("instances[2] says: {}", instances[2].toString() ); // Now assertions fail. assert( cast(c1) instances[1] !is null); assert( cast(c2) instances[2] !is null); return 0; }It works fine until the last two asserts: The casting does not work, why? I checked the casts to void, the addresses are correct. Also the instances identify themselves correctly. WTF? It also does not help to drop the (C) decoration, this only turns the name of the exported symbol.
Any thoughts?
Ciao
Tom












