views:

91

answers:

2

I have a MS C++ project (let's call it project A) that I am currently compiling as a static library (.lib). It defines a global variable foo. I have two other projects which compile separately (call them B and C, respectively) and each links the shared static library A in. Both B and C are dll's that end up loaded in the same process. I would like to share a single instance of foo from A between B and C in the same process: a singleton. I'm not sure how to accomplish the singleton pattern here with project A since it is statically compiled into B and C separately. If I declare foo as extern in both B and C, I end up with different instances in B and C. Using a standard, simple singleton class pattern with a static getInstance method results in two static foo instantiations.

Is there any way to accomplish this while project A is statically compiled into B and C? Or do I have to make A a DLL?

A: 

Yes, you have to make A a shared DLL, or else define it as extern in B and C and link all three statically.

Jeremy Bell
Can you elaborate on what you mean by "link all three statically"? I am currently linking A statically into both B and C and declaring foo extern in B and C, yet I end up with multiple definitions of foo at runtime. I think you are saying I would need to link A and B statically into C (or A and C statically into B), or link A, B, and C statically into another library. Is that accurate? Thanks!
Zach
The last one, except substitute "another library" with "the final executable". Don't link any of the libraries together. Instead, link A, B, and C statically with your final executable. Any symbols from A that are used in B or C should be declared as extern in B and C, but not defined. If you link A, B, and C into another shared library, you just have to make sure that this library encapsulates the singleton from A, because if A is linked statically to the executable and the executable accesses A's static data directly, it will get a different copy than the lib.
Jeremy Bell
A: 

No - they are not shared.

From Richter's 'Windows via C/C++' (p583):

When one process maps a DLL image file into its address space space, the system creates instances of the global and static data variable as well.

So, if you need to share a resource between multiple executables you will need to create a shared kernel object of some sort. I would suggest creating a named file mapping, which you can then use to read and write to from the separate processes (with appropriate Mutex exclusion, of course.)

Ragster