Thread overview
export classes from DLLs
May 08, 2006
John C
May 08, 2006
pragma
May 08, 2006
John C
May 08, 2006
Anyone ever got classes to export from DLLs correctly? I've searched the forum and it seems each effort has only got so far.

Using a factory method in the DLL works, but that's not what I'm trying to accomplish. If I try to create an instance in a program using the DLL, the compiler complains about an undefined symbol.

mydll.d implementation module
# // DllMain/gc_init etc omitted for brevity
#
# export class Dog {
# 	export static Dog create() {
# 		return new Dog;
# 	}
# 	char[] bark() {
# 		return "Woof";
# 	}
# }

mydll.di import module
# class Dog {
# 	static Dog create();
# 	char[] bark();
# }

mydll.def
# LIBRARY "mydll.dll"
# EXETYPE NT
# EXPORTS

Compile DLL and create import library
> dmd mydll mydll.def
> implib /system mydll.lib mydll.dll

program.d
# import mydll;
# void main() {
# 	// Dog dog = Dog.create(); // This works
#	Dog dog = new Dog; // This doesn't
# 	dog.bark();
# }

Compile program
> dmd program mydll.lib

This produces the following error:
> program.obj
> Error 42: Symbol undefined __Class_7program3Dog

Adding __Class_7program3Dog to the EXPORTS list kills the error, but then the program throws an access violation.

When I compile classes into a static library (no DLL), this problem doesn't surface.
May 08, 2006
In article <e3njr2$lr0$1@digitaldaemon.com>, John C says...
>
>Anyone ever got classes to export from DLLs correctly? I've searched the forum and it seems each effort has only got so far.
>
>Using a factory method in the DLL works, but that's not what I'm trying to accomplish. If I try to create an instance in a program using the DLL, the compiler complains about an undefined symbol.
>
>mydll.d implementation module
># // DllMain/gc_init etc omitted for brevity
>#
># export class Dog {
># 	export static Dog create() {
># 		return new Dog;
># 	}
># 	char[] bark() {
># 		return "Woof";
># 	}
># }
>
>mydll.di import module
># class Dog {
># 	static Dog create();
># 	char[] bark();
># }
>
>mydll.def
># LIBRARY "mydll.dll"
># EXETYPE NT
># EXPORTS
>
>Compile DLL and create import library
> > dmd mydll mydll.def
> > implib /system mydll.lib mydll.dll
>
>program.d
># import mydll;
># void main() {
># 	// Dog dog = Dog.create(); // This works
>#	Dog dog = new Dog; // This doesn't
># 	dog.bark();
># }
>
>Compile program
> > dmd program mydll.lib
>
>This produces the following error:
> > program.obj
> > Error 42: Symbol undefined __Class_7program3Dog
>
>Adding __Class_7program3Dog to the EXPORTS list kills the error, but then the program throws an access violation.
>
>When I compile classes into a static library (no DLL), this problem doesn't surface.

The problem is that DLL's cannot export type information in the way you'd expect it to.  In essence, each DLL compiled with D has its own type tree, completely distinct from the type tree present in your .exe file.  Trace the cause of those access violations and you'll probably find they all terminate at failing implicit and explicit casts due to this.

The problem goes away when you use static linking since the linker will unify all the type information, yielding totally different behavior in your code.

Anyway, there are *plenty* of other gotchas with DLL's.  I strongly reccomend you read the following before you get too deep into your design: http://www.prowiki.org/wiki4d/wiki.cgi?BestPractices/DLL

And before you let that get you down, rest assured, I'm working hard to push DDL toward release: http://www.dsource.org/projects/ddl.



- EricAnderton at yahoo
May 08, 2006
pragma wrote:
> In article <e3njr2$lr0$1@digitaldaemon.com>, John C says...
> 
>>Anyone ever got classes to export from DLLs correctly? I've searched the forum and it seems each effort has only got so far.
>>
>>Using a factory method in the DLL works, but that's not what I'm trying to accomplish. If I try to create an instance in a program using the DLL, the compiler complains about an undefined symbol.
>>
>>mydll.d implementation module
>># // DllMain/gc_init etc omitted for brevity
>>#
>># export class Dog {
>># 	export static Dog create() {
>># 		return new Dog;
>># 	}
>># 	char[] bark() {
>># 		return "Woof";
>># 	}
>># }
>>
>>mydll.di import module
>># class Dog {
>># 	static Dog create();
>># 	char[] bark();
>># }
>>
>>mydll.def
>># LIBRARY "mydll.dll"
>># EXETYPE NT
>># EXPORTS
>>
>>Compile DLL and create import library
>>
>>>dmd mydll mydll.def
>>>implib /system mydll.lib mydll.dll
>>
>>program.d
>># import mydll;
>># void main() {
>># 	// Dog dog = Dog.create(); // This works
>>#	Dog dog = new Dog; // This doesn't
>># 	dog.bark();
>># }
>>
>>Compile program
>>
>>>dmd program mydll.lib
>>
>>This produces the following error:
>>
>>>program.obj
>>>Error 42: Symbol undefined __Class_7program3Dog
>>
>>Adding __Class_7program3Dog to the EXPORTS list kills the error, but then the program throws an access violation.
>>
>>When I compile classes into a static library (no DLL), this problem doesn't surface.
> 
> 
> The problem is that DLL's cannot export type information in the way you'd expect
> it to.  In essence, each DLL compiled with D has its own type tree, completely
> distinct from the type tree present in your .exe file.  Trace the cause of those
> access violations and you'll probably find they all terminate at failing
> implicit and explicit casts due to this.  
> 
> The problem goes away when you use static linking since the linker will unify
> all the type information, yielding totally different behavior in your code.
> 
> Anyway, there are *plenty* of other gotchas with DLL's.  I strongly reccomend
> you read the following before you get too deep into your design:
> http://www.prowiki.org/wiki4d/wiki.cgi?BestPractices/DLL
> 
> And before you let that get you down, rest assured, I'm working hard to push DDL
> toward release: http://www.dsource.org/projects/ddl.
> 
> 
> 
> - EricAnderton at yahoo

Thanks for the explanation and the link. It's a shame it won't work - I was hoping to compile a fairly sizable class library into a DLL which other projects would link to, instead of bringing in all the code. So much for that idea!

I've been keeping an eye on DDL for a while. It looks like it'll be suitable for the plug-in system I've wanted to work on.

John C.