instance of sub class created in a dll has wired behaviour when cast
liyu
yunwind at msn.com
Sun Mar 22 20:10:20 PDT 2009
I am not sure it's a bug of tango or dmd, so i post it here. The example
code as below
//file common
module common;
abstract class DummyA {
}
abstract class DummyB : DummyA {
}
abstract class Factory {
DummyB createDummy();
}
//file dll
module mydll;
import common;
import tango.sys.win32.Types;
import tango.io.Stdout;
import tango.stdc.stdio;
// The core DLL init code.
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:
tango.stdc.stdio._fcloseallp = null;
rt_term();
break;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
// Multiple threads not supported yet
return false;
}
g_hInst=hInstance;
return true;
}
class DummyC : DummyB {
}
class DllFactory : Factory {
override DummyC createDummy() {
return new DummyC; }
}
export extern(C) DllFactory create() {
return new DllFactory;}
//file test
module test;
import common;
import tango.sys.SharedLib;
import tango.util.log.Trace;
// declaring our function pointer
typedef extern (C) Factory function() createFunc;
createFunc dllcreate;
void main() {
if (auto lib = SharedLib.load(`mydll.dll`)) {
Trace.formatln("Library successfully loaded");
void* ptr = lib.getSymbol("create");
if (ptr) {
Trace.formatln("Symbol dllprint found. Address = 0x{:x}", ptr);
// binding function address from DLL to our function pointer
void **point = cast(void **)&dllcreate;
*point = ptr;
// using our function
auto factory = dllcreate();
auto dummy = factory.createDummy();
Trace.formatln(dummy.classinfo.name);
auto d2 = cast(DummyB)dummy;
assert(d2 !is null); //ok
DummyA a = dummy;
Trace.formatln(a.classinfo.name);
auto d3 = cast(DummyB)a;
assert(d3 !is null); //Assertion failure
} else {
Trace.formatln("Symbol dllprint not found");
}
lib.unload();
} else {
Trace.formatln("Could not load the library");
}
assert (0 == SharedLib.numLoadedLibs);
}
The result is:
Library successfully loaded
Symbol dllprint found. Address = 0x1000308c
mydll.DummyC
mydll.DummyC
tango.core.Exception.AssertException at test(35): Assertion failure
As you see, var a is a instance of DummyC which is a subclass of DummyB, but
the cast is failure.
More information about the Digitalmars-d
mailing list