dll和exe的共享节------多进程共享dll/exe全局变量
2015-02-28 17:42
253 查看
我们都知道同一个应用程序的多个实例之间并不会影响各自的变量,虽然他们的地址空间都是被该应用程序的映像内的物理存储器所提交,他们的数据和代码都是指向了该应用程序的映像,但是他们还是不会影响各自的变量,因为采取了copy-on-write机制,当有一个实例去修改共享的那个数据区的时候,那么操作系统会另外分配一个内存块,该内存块就是存放这个实例修改的数据,所以并不会影响其他的应用程序实例。
那么可执行文件或dll的多个实例之间怎么去共享全局数据呢?现在进入我们的主题-----共享节
什么是共享节呢?
.exe和dll文件的映像都是由许多节组成的,比如:.text,.data,.bss它们都有自己的作用。存放为初始化的变量呀,存放未初始化的变量呀,存放代码呀等等。。这些东西我们都不用管,编译器会帮我们做好一切的。
我们也可以定义自己的共享节:
[cpp] view
plaincopy
#pragma data_seg("Shared")
int g_data=3;
#pragma data_seg()
这里就定义了一个叫做:“Shared”的共享节,在该共享节中有一个初始化了的变量g_data,注意:不要以为放在这里面就以为一定在这个共享节中,如果你没有初始化这个变量的话,那么这个变量还是放在默认的未初始化的共享节中。这样还不能达到我们共享变量的目的。我们还必须告诉链接程序,这个节里面的变量是要共享的。
/SECTION:Shared,RWS。这是在你的工程--设置---链接中配的。我们还可以在你的程序中直接设置:
[cpp] view
plaincopy
#pragma comment(linker,"/section:Shared,rws")
这样就OK了。
下面我们来测试一下:
mydll.cpp:
[cpp] view
plaincopy
#pragma data_seg("Shared")
int g_data=3;
#pragma data_seg()
#pragma comment(linker,"/section:Shared,rws")
//__declspec(allocate("Shared"))int g_data=3;
extern "C" __declspec(dllexport) void setData(int temp)
{
g_data=temp;
}
extern "C" __declspec(dllexport) int getData()
{
return g_data;
}
dllCallOne.cpp:
[cpp] view
plaincopy
#include<iostream>
#include<windows.h>
using namespace std;
extern "C" {
typedef void (*PFN_setData)(int);
typedef int (*PFN_getData)();
}
void main()
{
HINSTANCE hinstance=LoadLibrary("D:\\mydll.dll");
if(hinstance)
{
PFN_setData setData=(PFN_setData)::GetProcAddress( hinstance,"setData");
PFN_getData getData=(PFN_getData)::GetProcAddress( hinstance,"getData");
if(setData&&getData)
{
setData(4);
getchar();
int temp=getData();
cout<<temp<<endl;
}
}
}
dllCallTwo.cpp:
[cpp] view
plaincopy
#include<iostream>
#include<windows.h>
using namespace std;
extern "C" {
typedef void (*PFN_setData)(int);
typedef int (*PFN_getData)();
}
void main()
{
HINSTANCE hinstance=LoadLibrary("D:\\mydll.dll");
if(hinstance)
{
PFN_setData setData=(PFN_setData)::GetProcAddress( hinstance,"setData");
PFN_getData getData=(PFN_getData)::GetProcAddress( hinstance,"getData");
if(setData&&getData)
{
int result=getData();
cout<<result<<endl;
getchar();
}
}
}
这样就实现了我们的多进程共享dll全局变量的目的了。
大家细心一点还会发现我在dll文件中注释了一行:
//__declspec(allocate("Shared"))int g_data=3;
这句话的意思就是:我就是要把这个变量放入到Shared共享节中。虽然它没有在那个节中定义,也不管这个变量有没有初始化。大家可以测试一下,把在共享节中的那个g_data删除,把这句话取消注释,同样也可以达到目的
那么可执行文件或dll的多个实例之间怎么去共享全局数据呢?现在进入我们的主题-----共享节
什么是共享节呢?
.exe和dll文件的映像都是由许多节组成的,比如:.text,.data,.bss它们都有自己的作用。存放为初始化的变量呀,存放未初始化的变量呀,存放代码呀等等。。这些东西我们都不用管,编译器会帮我们做好一切的。
我们也可以定义自己的共享节:
[cpp] view
plaincopy
#pragma data_seg("Shared")
int g_data=3;
#pragma data_seg()
这里就定义了一个叫做:“Shared”的共享节,在该共享节中有一个初始化了的变量g_data,注意:不要以为放在这里面就以为一定在这个共享节中,如果你没有初始化这个变量的话,那么这个变量还是放在默认的未初始化的共享节中。这样还不能达到我们共享变量的目的。我们还必须告诉链接程序,这个节里面的变量是要共享的。
/SECTION:Shared,RWS。这是在你的工程--设置---链接中配的。我们还可以在你的程序中直接设置:
[cpp] view
plaincopy
#pragma comment(linker,"/section:Shared,rws")
这样就OK了。
下面我们来测试一下:
mydll.cpp:
[cpp] view
plaincopy
#pragma data_seg("Shared")
int g_data=3;
#pragma data_seg()
#pragma comment(linker,"/section:Shared,rws")
//__declspec(allocate("Shared"))int g_data=3;
extern "C" __declspec(dllexport) void setData(int temp)
{
g_data=temp;
}
extern "C" __declspec(dllexport) int getData()
{
return g_data;
}
dllCallOne.cpp:
[cpp] view
plaincopy
#include<iostream>
#include<windows.h>
using namespace std;
extern "C" {
typedef void (*PFN_setData)(int);
typedef int (*PFN_getData)();
}
void main()
{
HINSTANCE hinstance=LoadLibrary("D:\\mydll.dll");
if(hinstance)
{
PFN_setData setData=(PFN_setData)::GetProcAddress( hinstance,"setData");
PFN_getData getData=(PFN_getData)::GetProcAddress( hinstance,"getData");
if(setData&&getData)
{
setData(4);
getchar();
int temp=getData();
cout<<temp<<endl;
}
}
}
dllCallTwo.cpp:
[cpp] view
plaincopy
#include<iostream>
#include<windows.h>
using namespace std;
extern "C" {
typedef void (*PFN_setData)(int);
typedef int (*PFN_getData)();
}
void main()
{
HINSTANCE hinstance=LoadLibrary("D:\\mydll.dll");
if(hinstance)
{
PFN_setData setData=(PFN_setData)::GetProcAddress( hinstance,"setData");
PFN_getData getData=(PFN_getData)::GetProcAddress( hinstance,"getData");
if(setData&&getData)
{
int result=getData();
cout<<result<<endl;
getchar();
}
}
}
这样就实现了我们的多进程共享dll全局变量的目的了。
大家细心一点还会发现我在dll文件中注释了一行:
//__declspec(allocate("Shared"))int g_data=3;
这句话的意思就是:我就是要把这个变量放入到Shared共享节中。虽然它没有在那个节中定义,也不管这个变量有没有初始化。大家可以测试一下,把在共享节中的那个g_data删除,把这句话取消注释,同样也可以达到目的
相关文章推荐
- dll和exe的共享节------多进程共享dll/exe全局变量
- DLL和EXE怎样共享全局变量?
- 进程间同步(互斥) 以及 同一DLL的不同进程copy共享全局变量
- 使用DLL在多个进程间共享全局变量
- DLL和EXE怎样共享全局变量?
- DLL和EXE怎样共享全局变量?
- DLL和EXE怎样共享全局变量?
- dll和exe的共享节------多进程共享dll/exe全局变量
- Linux共享库(动态库)与进程之间全局变量是无法共享的
- 多个进程范文DLL中的函数/全局变量/数据共享段问题
- Linux共享库(动态库)与进程之间全局变量是无法共享的
- linux动态链接库全局变量共享问题&DLL共享数据段
- Linux共享库(动态库)与进程之间共享全局变量可行性分析
- Python 多进程默认不能共享全局变量
- linux动态链接库全局变量共享问题&DLL共享数据段
- dll和exe的共享节------多进程共享dll/exe全局变量
- Linux共享库(动态库)与进程之间全局变量是无法共享的
- 当调用的DLL中有全局变量时调用它的多个实例是否共享同一个全局变量
- linux动态链接库全局变量共享问题&DLL共享数据段
- dll(动态链接库)之间以及和exe之间的函数、类或全局变量互传