Skip to main content
GameDev.net gamedev.net
🔒 Locked

Engine design issue (Plugins, DLLs)

Started by wiegje85 Jun 8, 2010 at 4:43 PM 2 replies 1k views
Original Post
wiegje85
wiegje85
Greetings!

I am running into a little snag when it comes to my engine design. I wanted to create a very powerful, dynamic architecture using a plugin system in combination with DLLs.

Image and video hosting by TinyPic

So I have my application.exe, this executable is linked with a .lib and .dll called Engine.Core.dll. From Application.exe I call a bunch of static functions in the DLL:
int main(){    Engine::Create(); // create new instances of the modules in the form of plugins    Engine::Run(); // run engine while its running    Engine::Release(); // when we get here, we release resources    return 0;}


The problem
...is that when I try to call a (static) function in my Engine.Core.dll from another plugin, say RandomPlugin0.dll calls:
int val = (int)Settings::Get("varname");


I then get linker errors, saying there's undefined static external symbols, i.e. bool Engine::m_Running.

Where the class and (static) function Settings::Get(...) is defined inside Engine.Core.dll. I am already exporting the class Settings from Engine.Core.dll using __declspec(dllexport). Now I figured that I need to do something weird for static classes? But what? Google is not my friend.

I figured I can use the singleton idiom for my engine's Core class, but then I still need static members, static accessors, etc. to get the address of my engine's instance.

How is this usually solved? How do I create two-way communication between several DLLs? Basically I want all DLLs to call functions from each other through the Engine.Core.dll's interface for said plugins, should they need to.


Much rating awaits those who can help ;) Thanks!

[Edited by - wiegje85 on June 8, 2010 4:59:13 PM]
Burnhard
Burnhard
What can I say - the architecture you're trying to develop here is a recipe for a giant spaghetti graph. I've seen it before: developer's big dream is to produce the most generic, do-everything system possible and ends up in a pickle.

To give advice on architecture is probably not what you're wanting but I will give it anyway:

...each plug-in should have the same interface, or if you want define a set of interfaces (a set of plugins that do A, a set that do B, etc.). The engine should talk to the plugins by calling methods on their interfaces. The plugins should not call "up" into the engine. If they do so, every time you modify the engine interface, you will have to compile/modify every single plugin DLL. This is not good.

If the plugin needs state, it should be passed as part of the interface definition for a plugin. The state passed should be objects of as fine a granularity as possible - that is to say, you should not pass in a pointer to an "Engine" to your plug-in. If, for example, you plug-in did image processing, you would pass in a reference to an image.



wiegje85
wiegje85
Quote:
Original post by Burnhard
What can I say - the architecture you're trying to develop here is a recipe for a giant spaghetti graph. I've seen it before: developer's big dream is to produce the most generic, do-everything system possible and ends up in a pickle.

To give advice on architecture is probably not what you're wanting but I will give it anyway:

...each plug-in should have the same interface, or if you want define a set of interfaces (a set of plugins that do A, a set that do B, etc.). The engine should talk to the plugins by calling methods on their interfaces. The plugins should not call "up" into the engine. If they do so, every time you modify the engine interface, you will have to compile/modify every single plugin DLL. This is not good.

If the plugin needs state, it should be passed as part of the interface definition for a plugin. The state passed should be objects of as fine a granularity as possible - that is to say, you should not pass in a pointer to an "Engine" to your plug-in. If, for example, you plug-in did image processing, you would pass in a reference to an image.


hi,

sorry i wasnt very clear in my post about it, but i actually do have separate interfaces for each possible plugin. I am not looking for the most abstract design, but am rather looking for a flexible design. Example: Win32's api is different in creating windows as is OSX's. So what I have is a type of "semantic" in what I call a Plugin Map that says that the engine is to use the Window.Win32 or Window.OSX plugin. The same goes for the render core: D3D9, D3D10, D3D11, OpenGL, Software, whatever, all can be implemented dynamically using this approach. This way, I want to create an easier way to create an platform independant engine.

Now I have that settings class, and I want all plugins to read from the loaded settings database. This has to be instanced somewhere, or be a static class. Now I can use a shared interface and compile Settings.lib into every dll, but that means that I am instancing my settings all over the place, while I have a central "hub" called Engine.Core.dll.

And that is the exact issue.

[Edited by - wiegje85 on June 9, 2010 2:50:31 AM]
Matt Green
Matt Green
Look up how something like COM works. Components programming is the only way to do this nicely. For settings, you'd have an interface class and then an implementation class. Plugins get an instance to the implementation class by passing the interface class to a registry that maps the interface class to the implementation class.

if(ISettings* settings = _registry.Get<ISettings>()){    _volume = settings->Get<int>("volume", 0);    _music = settings->Get<bool>("music", false);}

Topic Locked

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

Sign in to reply to this topic.