singleton instance main app - dll

Started by
4 comments, last by stephanh 18 years ago
Hi, i have a little problem sharing a singleton between a "main" application and a DLL plugin loaded in that main application. The singleton is a kind of registry for auto registration of the plugins. Singleton Source The setup is as follows: Framework library: edelweiss.dll contains the autoregister.h and alot of engine stuff MyPlugin.dll: implements a interface from the framework and registers itself by creating a global instance of AutoRegister<KernelServer>::Proxy<MyPlugin> reg_myplugin_proxy; The application performs the following tasks - load all plugin dlls with LoadLibrary - now reg_myplugin_proxy gets instantiated - requests instance() form AutoRegister<KernelServer> and registers itself now i query AutoRegister<KernelServer>::instance()->getRegistered in the main application but now the instance is still 0, and a new instance is created. So in short: each, the dll and the main app create a separate instance of the singleton Question: why? instance_ shouldnt be NULL when called the 2nd time The autoregistration works absolutely flawless when used in the edelweiss.dll or in the main app. But now in a dynamically loaded dll. Thanks alot for hints. regards, stephan
Advertisement
How does the DLL know about the singleton in the EXE? The DLL needs to ask the EXE for the singleton somehow, you can't just use the same singleton code in the DLLs and the EXE, or else ach DLL will create it's own instance of the singleton.

Two ways that I can see are:
  1. Export a function from the EXE that gives the DLL a pointer to the singleton (The DLL can grab the function using GetProcAddress(GetModuleHandle(NULL),"MyProc") in DllMain)

  2. Have a function in the DLL that is called by the EXE to initialize the plugin, and pass the pointer to the singleton here
If I understand your code correctly, that is [smile]
Quote:Original post by Evil Steve
How does the DLL know about the singleton in the EXE? The DLL needs to ask the EXE for the singleton somehow, you can't just use the same singleton code in the DLLs and the EXE, or else ach DLL will create it's own instance of the singleton.

Two ways that I can see are:
  1. Export a function from the EXE that gives the DLL a pointer to the singleton (The DLL can grab the function using GetProcAddress(GetModuleHandle(NULL),"MyProc") in DllMain)

  2. Have a function in the DLL that is called by the EXE to initialize the plugin, and pass the pointer to the singleton here
If I understand your code correctly, that is [smile]



Maybe i got that wrong from the MSDN docs, but address space is shared with the calling app when using DLLs (though, each app gets it's own dll instance).

That's why i thought that the "static AutorRegister::instance_" is really unique in that application + dlls (since in the same address space).

I found something similar in the OpenSceneGraph osgDB::Registry, the only difference is that there the instance definition is in the cpp file of the dll (edelweiss.dll in my case, the framework) and not a template in a header like in my setup.
And it seems to work in that project.

regards,
stephan
Static and global objects end up with their own copy in the module. So if you have 3 DLLs and 1 EXE, you have a copy of the global data for each DLL.

I'm not sure how OpenSceneGraph works, but placing the definition in the CPP file shouldn't affect it. Unless you only include the CPP file in one module, so you'd only have one real instance of it. And that would cause compile errors for any other modules.

EDIT: A bit of an explanation about the first point: With Windows, when you declare a static or global object, it gets allocated a space in the EXE (or DLL) file. If you open up the EXE with a hex editor, you'll be able to see the object in it there. When Windows loads the module, it maps the file into memory, so your object now has a location in memory. If that's done with several files, you have several objects in memory. DLLs can share the address space with the EXE, meaning that the EXE can access memory allocated by the DLL and vice versa. So when you request the singleton from the EXE, the DLL just gives you the memory location of where the object has been mapped into memory.

I have a similar solution but with 1 global class per module.

In the exe I have a dllloader which will ask the dll for 1 function, like GetModuleInterface() which when successful will return the address of the (local)module in the dll. Through this module-class I am able to access the class factory of each dll.

Then there is the module-class code which is same file for every dll and the exe too. The module-class is derived from the abstract module interface class.

Best of all, I just need to include the module-class to the dll and after that everything registers automagically, and it is ready to be used.
thanks alot for the replies so far.

hmm, seems that it wont work the way i wanted it to work :). I loose alot of flexibilty (and "beauty") if i pass through pointers, that typed registration singleton worked for all kind of objects in my engine.

Still, i dig deeper into how OSG does what it does.

EDIT(1): It works, when autoregister is _no_ template. I dont really understand that.

EDIT(2): Got it working. With some minor modification at the base classes that has to be registered.

i marked the template AutoRegister with __declspec(dllexport)/dllimport and wrote a macro to do a fake registration to force the compiler to generate code for the template on the framework dll side (this is just necessary for dll plugins, if not done, we get a linker error at the plugin build time). Now the template isnt instantiated anymore for the plugin dll and registration for DLL and "internal" plugins work with the same code.

Thanks for all your hints and comments.

regards,
stephan

[Edited by - stephanh on March 30, 2006 9:00:31 AM]

This topic is closed to new replies.

Advertisement