Skip to main content
gamedev.net
🔒 Locked

Plugins - .DLL/.LIB question

Started by Drew_Benton 5 replies 2.2k views
Original Post
Drew_Benton
Drew_Benton
Hey everyone! Merry Christmas! Mr. Foster has written a great article on using plugins for your programs. It is here. However, there are some design concepts that I do not understand relating to dlls and lib files. When you use a .dll, you must link in the .lib - other wise the compiler cannot find the definitions of the functions used. You must also have a header file telling the compiler to "import" in those functions. When you link in the library - does it not add to the file size of the executable? I always thought when you link in .libs, it added some overhead - however, I noticed that it was not in my program from that article. To show this I copied the program's exe size before and after including the lib - 16.0 KB (16,384 bytes) - before 16.0 KB (16,384 bytes) - after Now I know there is another type of library file - the static that is compiled into the .exe, so you do not have to use a .dll. Was I just misinterpereting the way .dlls work - as in the .dlls contain all the info for the functions - and the .libs just refrence it, but do not add anything to it? Furthermore, graphics apis that use .dlls, such as SDL, OpenGL, and DirectX - you have to use the .dll and .lib, so if im not mistaken than, using them adds no overhead to a program size? If anyone can confirm this or straighten things out for me, it would be much appreciated. Thanks! - Drew [Edited by - Drew_Benton on May 25, 2005 9:40:20 PM]
Promit
Promit
A lib always contains function definitions. In the case of a static lib, it will contain the complete function implementations, so yes, code can get much bigger there.

However, When you're working with a DLL file, the function implementations are, by definition, not even available. So the lib contains stub functions that the linker resolves to. All of your program calls are routed to the stubs in that lib, which will reroute the call to the actual DLL at runtime. So your code, which requires a static address to call, goes to that stub. It's in that stub that magic happens at runtime, making sure that it's code from the DLL that finally gets called.
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
abrken
abrken
Quote:
Original post by Drew_Benton
When you use a .dll, you must link in the .lib - other wise the compiler cannot find the definitions of the functions used. You must also have a header file telling the compiler to "import" in those functions.


Not really, you can have the dll function adress using GetProcAdress.
For doing this you must load the DLL first ofcourse.
This way, there is nothing append to your code from the DLL, not even from a LIB.

AbrKen
Drew_Benton
Drew_Benton
Ok thank you very much. I was scratching my head for a minute because I was always figuring by linking in the .lib, you would add size. I was thinking, what's the point of using plugins if you still have to link in the .dll and .lib.

Now I have to ask on the same topic - since you are doing the same process as using regular .dlls - what's the point then of using plugin's as Mr. Foster has said? You still have to link in the .lib file, use the .dll file, and include a .h file? It only seems that you are creating more work for yourself than solving. I do see the 'concept' of using plugins, because you can easily switch between components - such as the graphic apis - as that is desirable in engines, but as far as the code goes, I simply do not understand how that method does anthing different than using regular methods of accessing .dlls.

- Drew

[edit]

Quote:
Original post by abrken
Quote:
Original post by Drew_Benton
When you use a .dll, you must link in the .lib - other wise the compiler cannot find the definitions of the functions used. You must also have a header file telling the compiler to "import" in those functions.


Not really, you can have the dll function adress using GetProcAdress.
For doing this you must load the DLL first ofcourse.
This way, there is nothing append to your code from the DLL, not even from a LIB.

AbrKen


Now that you say that, and the plugin tutorial uses it. I think I may not be using the system correctly. What I'm trying to do is make the tutorial work - and it does - but by conventional means. From MSDN it says that
Quote:
If the function succeeds, the return value is the address of the exported function or variable.


When I read that I think I need to export 1 class variable from the .dll and not the actuall class itself - maybe that would explain why I am using the same methods as I always have for using .dlls. I will take another look. Thanks!

[/edit]

[Edited by - Drew_Benton on May 25, 2005 9:57:26 PM]
Promit
Promit
You will need to use GetModuleHandle and GetProcAddress for a plugin system, since the plugin system, by design, does not know at compile time what DLLs it will be loading. Using these functions, you can do things like finding every DLL in a "plugins" directory and attempting to load it.

There's a very effective way of doing this efficiently:

//let's call this, Plugin.h, a file which all plugins include//this is a base interface to, say, a window creator:class IWindow{public:    IWindow() { }    virtual ~IWindow() { }    virtual bool Create( int Width, int Height ) = 0;    virtual void Destroy() = 0;};//now, prototype a function:__declspec(dllexport) IWindow* GetInterface();


Now, every plugin DLL exports a single function, called GetInterface(). Inside the plugin, you can have an implementation of the IWindow interface -- but the host program never needs to know about it! All it knows is that it can call GetInterface to get a pointer to an IWindow interface that has an implementation behind it. Now, we can get that function via GetProcAddress and all is well.
SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.
ParadigmShift
ParadigmShift
Well there are several ways of doing what you're trying to do, but the basic outline is this:

Every plugin you will write will contain at least one exported function which is identical to all the others, which you define. For example:

CPlugin *registerPlugin(CApp *callingApplication);

CPlugin is a base class which has virtual functions for all your plugin functionality. When you create a particular plugin, you will implement the function:

class CNewPlugin : public CPlugin
{
...
};

CPlugin *registerPlugin(CApp *callingApplication)
{
return new CNewPlugin();
}

In your calling application, you can select a plugin to load at runtime and then get a CPlugin pointer like so:

typedef CPlugin * (*PLUGINPROCPTR)(CApp *);

HMODULE newPlugin = LoadLibrary(libname);
PLUGINPROCPTR proc = (PLUGINPROCPTR)GetProcAddress(newPlugin, "registerPlugin");
CPlugin *newPluginImpl = (proc)(thisApp);

You have to be careful about the paths Windows searches for the DLL, but otherwise this should work.

Hope that helps,

Tom
"E-mail is for geeks and pedophiles." -Cruel Intentions
Drew_Benton
Drew_Benton
Ok guys thanks a lot! I figured out that my problem was that I did not understand the whole loading .dlls at runtime concept. I took a look at MSDN - which I would have done earlier, but I didn't know the 'topic name' - and I figured out from their examples that you do not even need a .h file per se.

As ParadigmShift said towards the bottom, the "typedef CPlugin * (*PLUGINPROCPTR)(CApp *);" is the 'key' to using these plugins - which I didn't realize was just a function pointer! It makes total sense now what I need to do -

1. Make the simple .dll project | Link
2. Make the test program | Link
3. Try and figure out why the Plugin tutorial is so confusing. [wink]

Thanks for all the help! I will now redo this plugin system using MSDN instead and let you know if it works right.

- Drew

[edit] It works flawlessly! Thanks you all so much! [/edit]

[Edited by - Drew_Benton on May 25, 2005 9:46:33 PM]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.