I have hit a bit of a problem. I’ll try and explain as best I can but
I’m not great at doing this so bear with me. In my project I have a
static library which has many things, namely a singleton “Root” object
which can be accessed from any other part of the library. This Root
object is created by the user in their own application when using the
library something like this:
DF::Root *root = new Root();
Now along with the static library I have external “Modules” or DLLs. Now
My problem is that I want to be able to access the same Root singleton
from my DLL. I have linked by DLL to the static library and in one of
the methods I call something like this:
DF::Root->GetSingletonPtr()->GetLogger()->Log(“Direct3D 9 Render
Device created succesfully”, DF::EMT_NORMAL);
But calling GetSingletonPtr() from the DLL does not get the one that the
static library is using, in fact it returns nothing because there is no
Root object that the DLL can get to. So What I’m asking is how can I get
my DLL to access the singleton being used by the static library?
Sorry if that didn’t make much sense. If you need me to clarify
something let me know. Thanks in advance.
EDIT: What I want to achieve is something like the Ogre engine. It’s a
similar setup to mine but it seems to be able to use the singleton from
the DLLs fine…
Please log in or register to post a reply.
Perhaps I am misinterpreting your question, but it sounds like you want
your DLL to access something in your app/library?
Perhaps I’m wrong, but isn’t the idea of a DLL to be a library that your
app can pull from and use the functionality from? The DLL techinically
wouldn’t know about anything going on in the app or another library?
I was under the impression that a DLL was loaded into the same, for want
of a better word, “memory pool” as the application using it. So
shouldn’t it be able to access the memory I want it to?
Maybe your right but i thought you write DLL’s to be “application”
independant, so with that being said, how would the DLL know what the
You should be able to plug a dll into any application and use the
functionality of it without having to set up your own variables for it
to read from.
Think of DirectX
You add the header file and include the library for your game, build
then when you deploy, the machine has to have the DX dll’s to run. All
the objects you use in your game are derived from the dx library/dll.
This is my understanding of it, but perhaps im wrong.
If you included the same static library in your DLL as you did in your
app, and the declaration of a variable pointing to the object which your
DLL is trying to access is found in the static library’s code, your
application and your DLL are both going to have their own > SEPERATE <
copy of the variable.
If you initialize the variable in your application, your application’s
copy of the variable will have a value, but when you refer to that
variable in the DLL, you will be refering to the DLL’s copy of that
variable. Static libraries are built into your applications and DLLs,
not connected to during runtime, so their variables aren’t shared among
all things that use them.
Use static libraries only for reuseable methods that don’t depend on
outside variables, such as useful math functions:
float dot3( vec3 v );
Now, if you declare a variable in the DLL, and make it available to the
Your DLL’s source:
MYDLLAPI SomeClass *theOneClass = NULL;
Then your application can set that variable:
theOneClass = new SomeClass( );
Then when your DLL acts on that class:
MYDLLAPI void SomeFunction( void )
if( theOneClass )
It will be affecting an object provided by the application, which the
application can also use at will.
You could also pass an instance of an object class defined in a static
library to the DLL.
MYDLLAPI void DoSomethingToSomething( SomeClass *pob )
OK Well I have temporarily fixed the problem by getting the static
library to pass a pointer to the Root object to the DLL when it’s
loaded. But for some reason even though I pass this poniter
GetSingletonPtr() does not work but other get methods, GetLogger(), do.
I don’t understand how the OGRE engine has done this?
Dag239, freezo, a DLL can certainly access things from the application,
as they are indeed in the same memory space. However, the memory
addresses of application objects will not be known to the DLL unless you
pass these addresses to the DLL upon load.
Dom, I don’t know why some of your methods work but others don’t. Could
you post some of your code?
OK In the application which uses the static library:
dfRoot = new DF::Root();
Creating a new Root object. This is the object that’s used by the
static library. E.g. The static library can do this:
Root::GetSingletonPtr()->GetLogger()->Log("Module " + name + " has been loaded successfully", EMT_NORMAL);
In the Roots constructor it creates a new Render Device. The
constructor for the Render Device will then go ahead and load the
external module and get some function pointers:
//Load the appropriate module
Root::GetSingletonPtr()->GetLogger()->Log("Direct3D 9 Renderer is not supported on this platform", EMT_ERROR);
//Get pointers to the functions in the module
m_createRenderDevice = (_CreateRenderDevice)m_module.GetProc("CreateRenderDevice");
m_releaseRenderDevice = (_ReleaseRenderDevice)m_module.GetProc("ReleaseRenderDevice");
//Create the render device
m_renderDevice = CreateRenderDevice(Root::GetSingletonPtr());
As you can see I call CreateRenderDevice, which in turn calls the
equivalent function implemented in the DLL. I pass it a copy of my
Singleton pointer for the Root (Root::GetSingletonPtr()).
This is the the CreateRenderDevice function definition in the DLL:
//In the module header file
DF::Root *Root = 0;
//In the source file
DF::IRenderDevice *CreateRenderDevice(DF::Root *root)
Root = root;
renderDevice = new DF::D3D9RenderDevice();
Root->GetLogger()->Log("Direct3D 9 Render Device created succesfully", DF::EMT_NORMAL);
As you can see in the previous function I do Root->GetLogger()…
rather than Root::GetSingletonPtr()->GetLogger()… If I call the
GetSingletonPtr() method inside the module it returns a NULL pointer. I
think this may have something to do with the way I pass the Singleton
pointer, and a Singleton can’t have a pointer to a singleton? :S
I hope this makes it easier for you to understand.
When you compile the DLL, do you compile in the module that contains the
definition of Root and GetSingletonPtr, or do you just refer to the
header file that contains the class interface?
You should be doing the latter. If you were to compile the module into
the DLL, then the DLL would contain its own copy of the Root class and
therefore a different singleton instance.
It looks to me like this may be what you are doing. If you put a call to
Root::GetSingletonPtr from within the DLL, you ought to receive a linker
error, because this function isn’t part of the DLL. If you don’t, you’ve
probably got two copies of Root, one in the application, and one in the
DLL, each with its own singleton object. The second one isn’t getting
initialized which is why you’re getting NULL.
You can’t call a function inside an application from a DLL unless you’ve
first passed its function pointer. So you could use
Root::GetSingletonPtr in the DLL, if you declared that name in the DLL
as a function pointer, and sometime during initialization set it to the
address of the Root::GetSingletonPtr in the main application.
However, in my opinion singletons are more trouble than they’re worth. I
would just stick with what you have now - passing a pointer to the Root
object directly to the DLL. That’s more elegant and clear, IMHO.
Thanks that does make sense. And yeah I think I will stick to what I
have at the moment. It works nicely. Thanks for all the help.
OK Unrelated to this topic but I’m just gonna use this thread anyway.
There is a function in my DLL which is throwing uhnadled exceptions
errors. I want to debug and find out whats causing it. (It seems
changing a value from 16 to 32 destroys it :S) but whenever I debug it
won’t load the symbols for the DLL so none of my breakpoints work. it
only works for the static library. Any help? I’m using MSVC++ 2005.