很抱歉,如果之前已经回答过这个问题;但是,所有类似的问题似乎都与DLL中的全局变量或静态变量相关,并与它们共享。
是否可以在两个独立的应用程序之间共享一个dll实例?
我有两个应用程序(appA,appB)和一个DLL(DLL)。
我看到appA是否有可能在DLL中调用一个函数,然后在堆上创建一个变量并将其存储在DLL中。稍后,我想让appB连接到DLL,并能够访问之前创建的变量。再次,抱歉,如果这个答案与dll中的静态和全局变量相同。
这是一些伪代码:
(theDLL)
class VariableHolder
{
public:
void StoreVariable(int x)
{
mInt = new int(x);
}
int GetVariable()
{
return mInt;
}
private:
int mInt;
}
(的appA)
int main()
{
...
(assuming we got access to a VariableHolder singleton created in theDLL)
theVarialbeHolder.StoreVariable(5);
...
}
(程序appB)
int main()
{
...
(assuming we got access to a VariableHolder singleton created in theDLL)
if (theVarialbeHolder.GetVariable() == 5)
{
cout << "Hurray, how did you know?";
}
...
}
答案 0 :(得分:3)
这完全不可能 - 因为两个进程的地址空间不同(因为它们是虚拟的,由内核创建),因此一个中的有效指针不能在另一个中工作。但是,您可以使用共享内存在进程之间传输原始标量数据(字符串,整数) - here's how.
答案 1 :(得分:3)
是的,这可以使用共享内存。它不需要使用共享DLL。
取决于操作,方法有所不同:
在Windows上,共享文件用于映射到内存中(请参阅Creating Named Shared Memory)。
在Linux和Unix上,有直接的功能来创建共享内存区域,例如: System V IPC。只需谷歌吧。
答案 2 :(得分:2)
几乎所有现代操作系统上的共享库都是由共享的只读可执行文件和数据页实现的,同时映射到使用给定库的任何进程的地址空间。虽然在Windows上(与大多数Unix系统相比),这种共享也可以扩展到DLL中的读写数据段,因此可以在DLL中创建全局变量,在加载了DLL的所有图像之间共享。为实现这一目标,需要分两步完成。首先,您告诉编译器将共享变量放在新的命名数据部分中:
#pragma data_seg (".myshared")
int iscalar = 0;
int iarray[10] = { 0 };
#pragma data_seg ()
让所有这些变量静态地初始化非常重要,否则它们将最终进入.bss
部分。然后,您必须告诉链接器您希望使用.myshared
选项使/SECTION:.myshared,RWS
部分具有共享读写属性。
这种机制比创建和绑定到命名共享内存对象要简单得多,但它只允许共享静态分配的全局变量 - 您不能使用它来共享堆上的数据,因为堆是进程私有的。对于任何更复杂的内容,您应该使用共享内存映射,即在MSDN页面上显示,链接在H2CO3的答案中。
答案 3 :(得分:1)
这是不可能的。 DLL可以在2进程中共享,但数据不是。它是共享的代码或程序映像(即逻辑或指令),而不是数据。每个Dll都映射到加载它的进程的虚拟地址空间,因此数据要么位于进程的数据部分,要么位于堆栈上(如果它是函数的本地数据)。当进程正在执行时,其他进程数据的地址不可见。
您需要对虚拟内存以及内存管理单元(MMU)的工作方式进行一些阅读。操作系统,CPU,MMU协同工作使其成为可能。可靠的方法是进程间通信。您可以使用共享内存,其中每个进程都具有虚拟地址形式的数据副本,但它最终映射到相同位置到真实存储器,即真实地址。操作系统使它成为可能。
答案 4 :(得分:0)
这是@ H2CO3所指出的,因为地址空间不同而无法实现。
但是,根据您的问题,看起来您需要围绕该DLL或服务的代理进程,然后不同的进程可以连接到该代理进程/ exe并使用共享内存。
答案 5 :(得分:0)
您必须使用共享内存(如上所述)。
我建议使用boost进程库。请参阅有关共享内存的文档 - Shared memory between processes