Shared global variable in C++ static library

2020-02-05 10:21发布

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?

3条回答
我欲成王,谁敢阻挡
2楼-- · 2020-02-05 10:52

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.)

查看更多
3楼-- · 2020-02-05 10:53

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

查看更多
别忘想泡老子
4楼-- · 2020-02-05 10:58

I get this problem actualy :

I have A.EXE linked with B.LIB. I have C.DLL also linked with B.LIB.

As you can see, these two program are linked with B.LIB

Now, when required, the A.exe go load C.DLL. After loading, A.EXE and C.DLL each have separated B.LIB for code and data

The problem it is possible to have a B.LIB "fantom" linked with C.DLL to use the already loaded in A.exe?

I think no. It's a limitation from Window. In Linux you can, if I'm remember correctly. That was the regarded by the -fPic option of GCC. But not sure.

The solution to share global/static data stored in B.LIB with A.EXE and C.DLL is to use shared class/interfaces. Your A.EXE send interface to C.DLL with a data/interface pointer to the B.LIB stored in A.EXE.

In other words, if your C.DLL need to set/shared state of a static variable in B.LIB, your A.EXE must initializ C.DLL with the interface to permit data exchange with the B.LIB in A.EXE.

In all case, the B.LIB stored in C.DLL continue to bloat the global program because of the duplicate code from B.LIB in A.EXE and C.DLL

To reduce the global bloating, you must divide your A.LIB in more D.DLL, E.DLL that are loaded by A.EXE and transmited thru interface to your C.DLL

To reduce the bloated code to zero, you must use full independant interface method.

查看更多
登录 后发表回答