Help! dynamically linking a class in a DLL
by William Finlayson · in Technical Issues · 04/18/2001 (7:29 am) · 6 replies
A bit of background first to explain what I need -
In the past, when I have made classes in DLL's, I have made a header file with the class description in it, and wrote out all the class functions inside a DLL, adding "extern" to all the public functions. When I wanted to use the class in a project, I would add the header file to my project, then statically link to the DLL, no problems with that, but now I need to dynamically link to classes inside DLL's, and I have no idea how to go about it. I need to be able to use the class in the same way as if I had statically linked to it,as in calling "class.function(params)". Can anyone help or provide a code sample or something? Thanks.
In the past, when I have made classes in DLL's, I have made a header file with the class description in it, and wrote out all the class functions inside a DLL, adding "extern" to all the public functions. When I wanted to use the class in a project, I would add the header file to my project, then statically link to the DLL, no problems with that, but now I need to dynamically link to classes inside DLL's, and I have no idea how to go about it. I need to be able to use the class in the same way as if I had statically linked to it,as in calling "class.function(params)". Can anyone help or provide a code sample or something? Thanks.
About the author
#2
Let me see, if you use GetProcAddress, then you can get the address of one of the class's functions, but then how would you make it so that when you call class.function(), the function at the address you got is called?
04/18/2001 (10:12 am)
I'm not quite sure how it would work though, maybe you could give me an example of how you would do that with a class?Let me see, if you use GetProcAddress, then you can get the address of one of the class's functions, but then how would you make it so that when you call class.function(), the function at the address you got is called?
#3
You'll have to create a factory-function that returns the class that has been cast to a comman ancestor. A la (pseudocode):
In MyGame (ignorant of CCoolPerson, knows CPerson):
GetPerson = GetProcAddr(MyDLL, "GetPerson");
CPerson* Person = GetPerson();
In MyDLL (knows CPerson, knows CCoolPerson):
CCoolPerson : public CPerson = {}
GetPerson { return (CPerson*)new CCoolPerson; }
Relatively poor example, but hopefully you get the picture.
04/18/2001 (11:20 am)
I haven't seen any way to dynamically load a class by simple declaration.You'll have to create a factory-function that returns the class that has been cast to a comman ancestor. A la (pseudocode):
In MyGame (ignorant of CCoolPerson, knows CPerson):
GetPerson = GetProcAddr(MyDLL, "GetPerson");
CPerson* Person = GetPerson();
In MyDLL (knows CPerson, knows CCoolPerson):
CCoolPerson : public CPerson = {}
GetPerson { return (CPerson*)new CCoolPerson; }
Relatively poor example, but hopefully you get the picture.
#4
Your class definition (in your .exe header) uses only purely virtual functions (read: abstract class) and then you use a class factory within the DLL to create instances of the class and return a pointer to the created object. You can dynamically link in the library when you need it from your program's executable. Your actual class within the DLL code is derived from (inherits) the abstract class definition. I hope this helps (and that I'm not way off base!)
04/18/2001 (12:14 pm)
This is my somewhat lax understanding of how COM works (which should do what you need):Your class definition (in your .exe header) uses only purely virtual functions (read: abstract class) and then you use a class factory within the DLL to create instances of the class and return a pointer to the created object. You can dynamically link in the library when you need it from your program's executable. Your actual class within the DLL code is derived from (inherits) the abstract class definition. I hope this helps (and that I'm not way off base!)
#5
04/18/2001 (12:48 pm)
Thanks for all the help, but I think I'm still missing something, looks like I'm going to have to do a bit of reading :)
#6
Thomas
04/22/2001 (1:12 pm)
Doh you wanted to do this with classes. The method posted above will work. Getting classes to work across DLL boundries have always been extremly painful. I did it for a network DLL i wrote once, and the problem you invariable end up having to deal with is that it's a ton of work to maintain all the interfaces. Everytime you need to change a function call you need to modify your pure virtual base class, the class defination on the DLL, and then the interface you exported out. Not fun maintianing 3 headerfiles. I'm sure you may be able to get away with 2 header files, but it's still a ton of work. :(Thomas
Thomas Tong
Thomas
Cut and paste from the docs.
------------
LoadLibrary
The LoadLibrary function maps the specified executable module into the address space of the calling process.
HINSTANCE LoadLibrary(
LPCTSTR lpLibFileName // address of filename of executable module
);
LoadLibrary can be used to map a DLL module and return a handle that can be used in GetProcAddress to get the address of a DLL function. LoadLibrary can also be used to map other executable modules. For example, the function can specify an .EXE file to get a handle that can be used inFindResource orLoadResource. Do not use LoadLibrary to "run" a .EXE file.