Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
289 views
in Technique[技术] by (71.8m points)

c++ - Global variable has multiple copies on Windows and a single on Linux when compiled in both exec and shared libaray

* Question revised (see below) *

I have a cpp file that defines a static global variable e.g.

static Foo bar;

This cpp file is compiled into an executable and a shared library. The executable may load the shared library at run time.

If I am on Linux there seem to be two copies of this variable. I assume one comes from the executable and one from the shared library. Other platforms (HP, Windows) there seems to be only one copy.

What controls this behavior on Linux and can I change it? For example is there a compiler or linker flag that will force the version of this variable from the shared library to be the same as the one from the executable?

* Revision of question *

Thanks for the answers so far. On re-examining the issue it is not actually the problem stated above. The static global variable above does indeed have multiple copies on Windows, so no difference to what I see on Linux.

However, I have another global variable (not static this time) which is declared in a cpp file and as extern in a header file.

On Windows this variable has multiple copies, one in the executable and one in each dll loaded up, and on Linux it only has one. So the question is now about this difference. How can I make Linux have multiple copies?

(The logic of my program meant the value of the static global variable was dependent of the value of the non-static global variable and I started accusing the wrong variable as being the problem)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I strongly suggest you read the following. Afterwards, you will understand everything about shared libraries in Linux. As said by others, the quick answer is that the static keyword will limit the scope of the global variable to the translation unit (and thus, to the executable or shared library). Using the keyword extern in the header, and compiling a cpp containing the same global variable in only one of the modules (exe or dll/so) will make the global variable unique and shared amongst all the modules.

EDIT: The behaviour on Windows is not the same as on Linux when you use the extern pattern because Windows' method to load dynamic link libraries (dlls) is not the same and is basically incapable of linking global variables dynamically (such that only one exists). If you can use a static loading of the DLL (not using LoadLibrary), then you can use the following:

//In one module which has the actual global variable:
__declspec(dllexport) myClass myGlobalObject;
//In all other modules:
__declspec(dllimport) myClass myGlobalObject;

This will make the myGlobalObject unique and shared amongst all modules that are using the DLL in which the first version of the above is used.

If you want each module to have its own instance of the global variable, then use the static keyword, the behaviour will be the same for Linux or Windows.

If you want one unique instance of the global variable AND require dynamic loading (LoadLibrary or dlopen), you will have to make an initialization function to provide every loaded DLL with a pointer to the global variable (before it is used). You will also have to keep a reference count (you can use a shared_ptr for that) such that you can create a new one when none exist, increment the count otherwise, and be able to delete it when the count goes to zero as DLLs are being unloaded.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...