Quiz of the day: Why does this not work?
TomD
t_demmer at nospam.web.de
Thu Nov 6 12:14:47 PST 2008
Hi,
this is about dmd and DLLs.
Given a simple object hierachy in 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";} }
and a main file that first does some sanity checks, and then loads and
calls a function in a DLL:
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 );
}
Finally, a DLL that is supposed to work on instances, 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
export 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() );
Trace.formatln("instances[0] is: {}", instances[0].classinfo.name );
Trace.formatln("instances[1] is: {}", instances[1].classinfo.name );
Trace.formatln("instances[2] is: {}", instances[2].classinfo.name );
// Boom!
assert( cast(c1) instances[1] !is null);
assert( cast(c2) instances[2] !is null);
return 0;
}
This is a real show stopper for using D with/for dynamic libraries.
Is there anything simple to fix this?
Ciao
Tom
More information about the Digitalmars-d
mailing list