我有一个MS C ++项目(我们称之为项目A),我目前正在编译为静态库(.lib)。它定义了一个全局变量foo。我有另外两个单独编译的项目(分别称为B和C),每个项目都链接共享静态库A.B和C都是dll,最终在同一个进程中加载。我想在同一个过程中从A和B之间共享一个foo实例:一个单例。我不知道如何用项目A来完成单例模式,因为它是分别静态编译成B和C.如果我在B和C中将foo声明为extern,我最终会在B和C中使用不同的实例。使用带有静态getInstance方法的标准简单单例类模式会导致两个静态foo实例化。
有没有办法实现这一点,而项目A被静态编译成B和C?或者我是否必须制作一个DLL?
答案 0 :(得分:4)
是的,您必须使A成为共享DLL,或者在B和C中将其定义为extern并静态链接所有这三个。
答案 1 :(得分:2)
不 - 他们没有分享。
来自Richter的'Windows via C / C ++'(p583):
当一个进程映射DLL映像文件时 进入它的地址空间空间 system创建全局的实例 和静态数据变量。
因此,如果需要在多个可执行文件之间共享资源,则需要创建某种类型的共享内核对象。我建议创建一个命名文件映射,然后您可以使用该映射从单独的进程读取和写入(当然,还有适当的互斥锁排除。)
答案 2 :(得分:0)
我实际上遇到了这个问题:
我将A.EXE与B.LIB联系起来。 我有C.DLL也与B.LIB联系。
如您所见,这两个程序与B.LIB链接
现在,在需要时,A.exe将加载C.DLL。 加载后,A.EXE和C.DLL分别为代码和数据分离B.LIB
问题是可以将B.LIB“fantom”链接到C.DLL以使用已经加载的A.exe吗?
我认为不是。这是Window的限制。在Linux中你可以,如果我没记错的话。这是GCC的-fPic选项所认可的。但不确定。
与A.EXE和C.DLL共享存储在B.LIB中的全局/静态数据的解决方案是使用共享类/接口。您的A.EXE向C.DLL发送接口,其中包含存储在A.EXE中的B.LIB的数据/接口指针。
换句话说,如果您的C.DLL需要在B.LIB中设置/共享静态变量的状态,那么您的A.EXE必须使用接口初始化C.DLL以允许与A中的B.LIB进行数据交换。可执行程序。
在所有情况下,存储在C.DLL中的B.LIB继续膨胀全局程序,因为A.EXE和C.DLL中的B.LIB重复代码
要减少全局膨胀,您必须将A.LIB分成更多由A.EXE加载的D.DLL,E.DLL并通过接口传输到C.DLL
要将膨胀代码减少为零,必须使用完全独立的接口方法。