using an API inside various (plugin) DLLs

Started by
2 comments, last by vicviper 19 years, 1 month ago
Let's say I have a core geommetry API for a 3D editor... Initially, I had the core API compiled in the main EXE. Now, I want to allow the load of plugins which will be able to modify the geommetry in different ways... the first problem I found is that, in order to do that, the plugin must access the full core API, that is in the main EXE... up to now, most programming mechanisms I know are designed to pass an API on a DLL to the Main program... not the other way. So, how can I access funcions on the main program from DLLs? (we're talking about 100s of functions) Also have another question related to DLL and APIs: It is safe to create an object in a DLL, and then delete it in the main program?
Advertisement
Wow, how come it alwasy seems the same topics pop up all at once [grin]. Take a look at my post here. I'd say take a look at the project to see one way of doing it. I did plugin research a while back, so that code was the result of a few weeks of research, but it's not final or perfect, but it is definitly a start! If you ahve any questions on it feel free to PM me, I should be able to remeber what the heck I was trying to do back then [lol].
As Drew was saying: No, you cannot create an object in the DLL and delete it from the main program, unless both the DLL and the EXE link to the DLL version of the CRT. Then it's safe (but still not a good idea IMO).

To pass an interface to the DLL, I usually do this:
//// Main header//class IPlugin{public:   IPlugin() {}   virtual ~IPlugin() {}   virtual void Release() = 0;   // Your normal plugin functions //   virtual void DoSomething(int n) = 0;};class IInterface{public:   IInterface() {}   virtual ~IInterface() {}  // Technically doesn't need to be virtual   // Methods you want the DLL to be able to call //   virtual HWND GetWindow() = 0;   // Etc...};extern "C" {PLUGIN_API IPlugin* CreatePlugin(IInterface* pApp);}//// In the DLL...//class CPlugin : public IPlugin{   IInterface* m_pInterface;public:   CPlugin(IInterface* pInterface) {m_pInterface=pInterface;}   virtual ~CPlugin() {}   virtual void Release() {delete this;}   virtual void DoSomething(int n)   {      // Whatever code you want here      SetWindowLong(m_pInterface->GetWindow(),GWL_USERDATA,n);   }};PLUGIN_API IPlugin* CreatePlugin(IInterface* pApp) {return new CPlugin(pApp);}//// In the EXE...//class CGeometryAPI : public IInterface{public:   CGeometryAPI() {}   virtual ~CGeometryAPI() {}   virtual HWND GetWindow() {return m_hWnd;}};

That probably needs a bit of explanation...

You have two interfaces - the plugin the app uses to talk to the plugin (IPlugin) and the interface the plugin uses to talk to the app (IInterface). To create the plugin, you call the CreatePlugin() export from the DLL (usually with LoadLibrary() and GetProcAddress()), passing it a pointer to the interface that you want it to be able to use.
When you're finished with the plugin, you call IPlugin::Release(), which just calls delete this;. Since that code is in the DLL, you're calling delete from inside the DLL (and you called new from in the DLL too), so that's all nice and safe.
hehe, well, I expected that answer, just wanted to be sure ^^

About passing a iInterface to the plugin, might be a bit difficult, as the core api uses several classes and subclasses, don't know how to pass all of them. Also, there's an additional problem: I have to export not only the interface, but the funcion pointers also, because code generated in the DLL would not be valid (due to being in a different memory heap)

I think the only solution I have is to move the core API to another DLL, and load that DLL from the main program and also from the plugin DLLs, that might be a good solution? and, Do I need to take special care with that DLL (apart from the new/delete heap problem) because that DLL will be shared by several DLLs and the main program?

This topic is closed to new replies.

Advertisement