Two instances of global variable created when DLL depends on static library
2008-07-10 10:50
441 查看
Новое обсуждение
![](http://i4.forums.community.microsoft.com/resources/images/arrow_dn_white.gif)
Ответить
Цитировать
Голосовать
![](http://i4.forums.community.microsoft.com/resources/images/arrow_dn_white.gif)
jbreaux[loc] - Posted в 2007年1月26日 16:08:48
The code below is a simple example that displays some behavior that I do not understand. I have a Visual C++ solution that creates a simple console application. The solution contains a Win32 console application project, a static library project, and a dll project. The console application project contains main.cpp:
//########## BEGIN main.cpp
#include "MyDLLClass.h"
#include "MyStaticLibClass.h"
int main() {
MyStaticLibClass mslc;
mslc.changeInt(2);
MyDLLClass mdc;
mdc.DllFunc();
}
//########## END main.cpp
The static library project contains MyStaticLibClass.h and MyStaticLibClass.cpp:
//########## BEGIN MyStaticLibClass.h
class MyStaticLibClass {
public:
void changeInt(int _Int);
};
//########## END MyStaticLibClass.h
//########## BEGIN MyStaticLibClass.cpp
#include "MyStaticLibClass.h"
int myGlobalInt = 0;
static int myStaticGlobalInt = 0;
void MyStaticLibClass::changeInt(int _Int) {
myGlobalInt = _Int;
myStaticGlobalInt = _Int;
}
//########## END MyStaticLibClass.cpp
Finally, the dll project contains MyDLLClass.h and MyDLLClass.cpp:
//########## BEGIN MyDLLClass.h
#ifdef DLL_EXPORTS
#define DLL_API __declspec(dllexport)
#else // #ifdef DLL_EXPORTS
#define DLL_API __declspec(dllimport)
#endif // #ifdef DLL_EXPORTS
class DLL_API MyDLLClass {
public:
void DllFunc();
};
//########## END MyDLLClass.h
//########## BEGIN MyDLLClass.cpp
#include "MyDLLClass.h"
#include "MyStaticLibClass.h"
void MyDLLClass::DllFunc() {
MyStaticLibClass mslc;
mslc.changeInt(4);
}
//########## END MyDLLClass.cpp
You can see that at runtime, MyStaticLibClass::changeInt() will first be called from the exe and then from the dll. The first time that MyStaticLibClass::changeInt() is entered, the global variables myGlobalInt and myStaticGlobalInt are both equal to 0 (as they should be). As the program exits from MyStaticLibClass::changeInt(), myGlobalInt and myStaticGlobalInt are equal to 2 (as they should be).
The behavior that I do not understand occurs the second time that MyStaticLibClass::changeInt() is entered (i.e., when it is called from the dll). At this time, the global variables are equal to 0 again (i.e., the values they are assigned when they are declared).
The following are the memory addresses of the global variables during each pass through MyStaticLibClass::changeInt():
First pass (called from the exe):
&myGlobalInt 0x00417178
&myStaticGlobalInt 0x0041717c
Second pass (called from the dll):
&myGlobalInt 0x10017168
&myStaticGlobalInt 0x1001716c
So it appears that two instances of each global variable are being created (even the file-static variable, myStaticGlobalInt); one instance is used by the code in the exe and the other instance is used by the code in the dll. Is this expected behavior? Is there any way to prevent the second instance from being created and to ensure that the exe and dll will both be accessing the same instance of each global variable?
Thank you,
Jim
Ответить
Цитировать
Голосовать
![](http://i4.forums.community.microsoft.com/resources/images/arrow_dn_white.gif)
Ответ
Mike DanesМодератор[loc] - Posted в 2007年1月26日 16:52:24
"So it appears that two instances of each global variable are being created (even the file-static variable, myStaticGlobalInt); one instance is used by the code in the exe and the other instance is used by the code in the dll. Is this expected behavior?"
Yes. A static library means that the code and variables it contains are linked in each dll/exe that use it. Not only the variables are duplicated but also the code for function changeInt will exist in both dll and exe. It basically behaves as if you have MyStaticLib.cpp files compiled in both dll and exe projects.
"Is there any way to prevent the second instance from being created and to ensure that the exe and dll will both be accessing the same instance of each global variable?"
Not if you are using a static lib. You need to use a dll for this (or depending on specific situation you can link the static lib only into the existing dll).
Ответить
Цитировать
Голосовать
![](http://i4.forums.community.microsoft.com/resources/images/arrow_dn_white.gif)
Предложить как ответ
einarosMVP, Модератор[loc] - Posted в 2007年1月26日 17:21:58
Would it break your design to invert the control somewhat? Keep the variables in the dll, and have both the main project and static library call into that to change them. That will work as you expect it to.
Ответить
Цитировать
Голосовать
![](http://i4.forums.community.microsoft.com/resources/images/arrow_dn_white.gif)
Предложить как ответ
jbreaux[loc] - Posted в 2007年1月27日 11:27:59
Hi Mike,
Thank you very much for your helpful response. A few follow-up questions:
1. Is this behavior specific to the Microsoft linker, or would I see this behavior using any linker on Windows?
2. Are all variables and all code from the static lib replicated in the dll even if they are not referenced in any way by the code in the dll?
3. The same code in my example works the way I intended when I build it on Linux using gcc (building the MyDLLClass project as a shared library). Do you know why it works in this case?
Thanks again,
Jim
Ответить
Цитировать
Голосовать
![](http://i4.forums.community.microsoft.com/resources/images/arrow_dn_white.gif)
Предложить как ответ
jbreaux[loc] - Posted в 2007年1月27日 12:26:55
Hi Einar,
Thank you for the suggestion. I will try to solve the problem doing something similar. I do not want to take the variables in question from the static library project and put them in the dll project corresponding to the one in the example. Instead I will move the variables (and the class that accesses them) to a new dll project (i.e. there will be two dlls).
Thanks,
Jim
Ответить
Цитировать
Голосовать
![](http://i4.forums.community.microsoft.com/resources/images/arrow_dn_white.gif)
Ответ
Mike DanesМодератор[loc] - Posted в 2007年1月27日 16:39:43
"1. Is this behavior specific to the Microsoft linker, or would I see this behavior using any linker on Windows?"
I don't know much about other linkers on Windows but I believe this is an OS characteristic, not a linker one. The way DLLs work is that every DLL/EXE has access to its own symbols (variables/functions etc.) even if another DLL/EXE contains a variable/function with the same name.
"2. Are all variables and all code from the static lib replicated in the dll even if they are not referenced in any way by the code in the dll?"
Normally unused variables are discarded when building with compiler optimizations turned on.
"3. The same code in my example works the way I intended when I build it on Linux using gcc (building the MyDLLClass project as a shared library). Do you know why it works in this case?"
As far as I know on Linux dynamic link libraries (.so) files work differently than Windows .dll files. On Linux if 2 .so files (or a .so file and the executable itself) contain a variable (or function) with the same name only one will get used.
相关文章推荐
- how to force global variable which define in a static library to initialize?
- When To initialize global and static data For DLL
- cannot open the disk XXX or one of the snapshot disks it depends on
- Failed to find the required library mclmcrrt8_5.dll on java.library.path 解决方法
- Use MFC in a Static Library,This may be due to a corruption of the heap....
- how to install NOkia SDK of Chinese Version when you meet a Error:"Could not load jvm.dll"
- How to recover NameNode HA, when one accidentally formated one of the two NameNodes
- mysql5.6 cmake 编译提示Library mysqlserver depends on OSLIBS -lpthread;m;rt;crypt;dl
- It Depends Deciding on the Correct Ratio of Developers to Testers
- Running Apache Spark GraphX algorithms on Library of Congress subject heading SKOS
- MMSEG: A Word Identification System for Mandarin Chinese Text Based on Two Variants of the Maximum M
- definition of dllimport static data member not allowed
- Be careful of static field when unit testing!
- error C2352: 'CView::OnInitialUpdate' : illegal call of non-static member function
- When it comes to two corresponding names,one of them will be forces \( \)
- When does the Oracle library for st_shapelib.dll need to be changed?
- You receive a "Setup Library wbemupgd.dll could not be loaded" error message when you use Add or Remove Programs in Windows Server 2003
- definition of dllimport static data member not allowed
- Running multiple instances of Xamarin Studio on a Mac
- global variables' initialization in static library