🔒 Locked
Static variable changes in dll
Advertisement
Original Post
Hi I have a problem. I have class A and class B, which are located in a dll. In WinMain (in my exe), I am setting A::myStaticVariable to some value. But when I from a method in class B check A::myStaticVariable it is null?! Does this make sense? Can the static variable be different from when it is in the exe, and when it is in the dll? I of course have checked (and rechecked) that A::myStaticVariable is not changed any where else.
In order to prevent different modules from creating their own copy of the static member variables, you should export the template from the DLL. This article shows the necessary syntax.
Many, many thanks! I have read (and reread) the article, but still can not get it working.
I have my singleton template class located in a dll:
template class __declspec(dllexport) Singleton {
static T* mySingleton;
}
And I have my class A, also in the dll:
class __declspec(dllexport) A: public Singleton {}
Now, as I understand from the article, I should import the template instantiation into my exe by writing (in the exe):
extern template class __declspec(dllimport) Singleton;
This compiles as it should, but my initial problem remains the same.
A check on A::mySingleton still yields a different result depending on whether it is done in the exe or in the dll.
Have I misunderstood something, or forgot something here?
I have my singleton template class located in a dll:
template
static T* mySingleton;
}
And I have my class A, also in the dll:
class __declspec(dllexport) A: public Singleton {}
Now, as I understand from the article, I should import the template instantiation into my exe by writing (in the exe):
extern template class __declspec(dllimport) Singleton;
This compiles as it should, but my initial problem remains the same.
A check on A::mySingleton still yields a different result depending on whether it is done in the exe or in the dll.
Have I misunderstood something, or forgot something here?
Hmm i use templates too for some of my code, but ive never run into such a problem. I believe your templated base class is all in the header? And this header is included in your exe as well?
I do it this way, (might not work for you, but might be worth a try)
Since my base class is all in the header, i do not export this.
template
class UniqueRegistry
{
....
}
For my derived classes, i export them in the DLL
class __declspec(dllexport) EffectRegistry : public UniqueRegistry
In my exe,
the header is included with a minor change(obviously i use a typedef to automate this rather than making 2 header files)
class __declspec(dllimport) EffectRegistry : public UniqueRegistry
And it appears to work with 1 copy of the instantiated object shared between DLL and exe. (Objects instantiated in DLL)
I do it this way, (might not work for you, but might be worth a try)
Since my base class is all in the header, i do not export this.
template
class UniqueRegistry
{
....
}
For my derived classes, i export them in the DLL
class __declspec(dllexport) EffectRegistry : public UniqueRegistry
In my exe,
the header is included with a minor change(obviously i use a typedef to automate this rather than making 2 header files)
class __declspec(dllimport) EffectRegistry : public UniqueRegistry
And it appears to work with 1 copy of the instantiated object shared between DLL and exe. (Objects instantiated in DLL)
Example code of template class with static member variable shared between DLL and executable:
dll_header.h:
main.cpp:
dll_main.cpp:
dll_header.h:
#ifndef TEMP_DLL_DLL_DLL_HEADER_H#define TEMP_DLL_DLL_DLL_HEADER_H#pragma warning(push)#pragma warning(disable : 4231)#ifdef COMPILING_TEMP_DLL_DLL #define DECL_SPEC __declspec(dllexport) #define EXP_TEMPLATE#else #define DECL_SPEC __declspec(dllimport) #define EXP_TEMPLATE extern#endiftemplate <typename T>class DECL_SPEC ClassWithStatic { public: static T value;};template <typename T> T ClassWithStatic<T>::value;EXP_TEMPLATE template class ClassWithStatic<int>;EXP_TEMPLATE template class ClassWithStatic<float>;DECL_SPEC void dll_function(void);#pragma warning(pop)#endifmain.cpp:
#include "../dll/dll_header.h"#include <iostream>int main(int, char **) { ClassWithStatic<int>::value = 5; std::cout << &ClassWithStatic<int>::value << ":" << ClassWithStatic<int>::value << std::endl; dll_function(); std::cout << &ClassWithStatic<float>::value << ":" << ClassWithStatic<float>::value << std::endl;} dll_main.cpp:
#include "dll_header.h"#include <iostream>void dll_function(void) { std::cout << &ClassWithStatic<int>::value << ":" << ClassWithStatic<int>::value << std::endl; ClassWithStatic<float>::value = 0.25; std::cout << &ClassWithStatic<float>::value << ":" << ClassWithStatic<float>::value << std::endl;}
No, they shouldn't have to do anything: notice in SiCrane's source code snippet:
You need to define COMPILING_TEMP_DLL_DLL when you create your dll; when the client includes your header file, they should NOT have COMPILING_TEMP_DLL_DLL defined. This way, they'll automatically use the __declspec(dllimport) and extern declarations.
#ifdef COMPILING_TEMP_DLL_DLL #define DECL_SPEC __declspec(dllexport) #define EXP_TEMPLATE#else #define DECL_SPEC __declspec(dllimport) #define EXP_TEMPLATE extern#endifYou need to define COMPILING_TEMP_DLL_DLL when you create your dll; when the client includes your header file, they should NOT have COMPILING_TEMP_DLL_DLL defined. This way, they'll automatically use the __declspec(dllimport) and extern declarations.
Ahh..of course!
I understood it as COMPILING_TEMP_DLL_DLL should be defined in a dll header - and when this then was included in the exe, it got defined, and then it wouldn't work.
But I'll just define it in the project settings of my dll, or in a header that is NOT included in the exe - then it should work!
Thank you - I bow to thee knights of über-coding! ...or something along those lines ;-)
I understood it as COMPILING_TEMP_DLL_DLL should be defined in a dll header - and when this then was included in the exe, it got defined, and then it wouldn't work.
But I'll just define it in the project settings of my dll, or in a header that is NOT included in the exe - then it should work!
Thank you - I bow to thee knights of über-coding! ...or something along those lines ;-)
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement