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