dll hell again (please help)

Started by
14 comments, last by Kippesoep 18 years, 10 months ago
I still cant get this working. This is to do with plugins in my app. I have a main exe project that uses SDL to load everything and it has a platform manager class that can load the specific renderer etc to be used. The renderer etc are stored as dll files. Now the main exe program creates singletons for the log file etc but I cannot use the log inside my renderer dll. I have the implementation of the singleton get functions overidden in the logs cpp file as well as setting the actual singleton to NULL. I used the OGRE export macro but with my engines name too and the log lass has the export prefix. In the properties of my main program i have declared the NON_CLIENT_BUILD part. Now my main app compiles but my renderer dll will not compile. I get errors like: OGLRenderer error LNK2001: unresolved external symbol "__declspec(dllimport) public: void __cdecl ENGINE::E_Log::Write(int,char const *,...)" (__imp_?Write@E_Log@ENGINE@@QAAXHPBDZZ) if I add the log file cpp file to the renderer dll project i get the error: h:\Programming\current Engine backup\stable\genesis 23-11-04-11-07\source\engine\E_Log.cpp(21): error C2491: 'ENGINE::E_Singleton<T>::m_Singleton' : definition of dllimport static data member not allowed with [ T=ENGINE::E_Log ] Don't know what's goin on there. Do any of you have any ideas as to how to solve this problem, it's driving me insane lol. [Edited by - JinJo on May 25, 2005 11:36:07 AM]
Advertisement
Just to clear up a bit, it isn't a question related to the OGRE engine, I just posted there as a few people were having the same problems, should I just post the detais here so no one needs to look at the link.
Fewer people are going to read your problem if you don't post it here. Copy/paste isn't really that difficult.

Does it work properly when you compile in Debug mode?
Kippesoep
Well now the problem is outlined above, I have taken the non build define out of my main program and put it in my renderer dll.

I get no compiler errors now but when I run and the renderer tries to write using E_Log::GetSingleton().Write(...);
I get an assertion error message and the debugger in msvc.net opens up the ostream file.

Any ideas whats happening?

Er... what's the assertion that fails?
Kippesoep
it says in log.cpp line 23, expression:m_singleton, which is where the log file implements the singletons get function and uses assert.

Removing this still causes it to break inside the ostream file, i dont know how to use the debugger of msvc well but i dont think thats the major problem.

The log is still workin in the main exe its only when called from the dll that it starts blowing up.

Also may i add that for some reson i have to include the log.cpp file in the dll project, which i think is stupid but ive had to do it with kernel and memory management stuff too as well as some utilities.

In this file there is the line, template<> E_Log* E_Singleton<E_Log>::m_Singleton = NULL;

I dont know if that is causing a problem.
Would you happen to be using MSVC6? AFAIK, That has a problem with using (its version of) the STL across process boundaries. A replacement, such as STLPort fixes that.
Kippesoep
nah im using VC++.net 2003.

Well, I just added the lines in the dll renderer:
new E_Log();
E_Log::GetSingleton().Init();

now when I use the write function in the dll it does not cause an assert but it overwrites the original logfile, all this was expected.

So basically the dll is not getting the singleton pointer that the main exe is using. I knew that too, so how do I get the dll to use the same singleton pointer? Without passing in pointers to the dlls etc as this is dirty and OGRE doesn't need to do this.

[Edited by - JinJo on May 25, 2005 11:19:05 AM]
Is the singleton instance pointer declared inside GetSingleton or as a static member?
Kippesoep
it's a static member.

the singleton .h file is as follows:
[Source]template<typename T>class E_Singleton{public:	static T* m_Singleton; public:	E_Singleton(void)	{		assert(!m_Singleton);		int offset = (int)(T*)1 - (int)(E_Singleton<T>*)(T*)1;		m_Singleton = (T*)((int)this + offset);	}	~E_Singleton(void)	{		assert(m_Singleton);		m_Singleton = 0;	}	static T* GetSingletonPtr(void); };[/Source]


inside the log.cpp file there is the following code:
[Source]template<> E_Log* E_Singleton<E_Log>::m_Singleton = NULL;E_Log& E_Log::GetSingleton(void){    assert(m_Singleton);    return *m_Singleton;}E_Log* E_Log::GetSingletonPtr(void){    return m_Singleton;}[/Source]


Maybe it's something to do with that constructor code being in the header? but then surely i don't have to have all the classes that derive from a singleton implement the constructor too? It's bad enough having to do these acces methods for them all.

Kippesoep rating++ for the continuous help so far.

This topic is closed to new replies.

Advertisement