www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - export classes from DLLs

reply John C <johnch_atms hotmail.com> writes:
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
parent reply pragma <pragma_member pathlink.com> writes:
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
parent John C <johnch_atms hotmail.com> writes:
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.
May 08 2006