我们都知道同一个应用程序的多个实例之间并不会影响各自的变量,虽然他们的地址空间都是被该应用程序的映像内的物理存储器所提交,他们的数据和代码都是指向了该应用程序的映像,但是他们还是不会影响各自的变量,因为采取了copy-on-write机制,当有一个实例去修改共享的那个数据区的时候,那么操作系统会另外分配一个内存块,该内存块就是存放这个实例修改的数据,所以并不会影响其他的应用程序实例。

那么可执行文件或dll的多个实例之间怎么去共享全局数据呢?现在进入我们的主题-----共享节

什么是共享节呢?

.exe和dll文件的映像都是由许多节组成的,比如:.text,.data,.bss它们都有自己的作用。存放为初始化的变量呀,存放未初始化的变量呀,存放代码呀等等。。这些东西我们都不用管,编译器会帮我们做好一切的。

我们也可以定义自己的共享节:

#pragma data_seg("Shared")
int g_data=3;
#pragma data_seg()

这里就定义了一个叫做:“Shared”的共享节,在该共享节中有一个初始化了的变量g_data,
注意:不要以为放在这里面就以为一定在这个共享节中,如果你没有初始化这个变量的话,那么这个变量还是放在默认的未初始化的共享节中。这样还不能达到我们共享变量的目的。我们还必须告诉链接程序,这个节里面的变量是要共享的。

/SECTION:Shared,RWS。这是在你的工程--设置---链接中配的。我们还可以在你的程序中直接设置:

#pragma comment(linker,"/section:Shared,rws")

这样就OK了。

下面我们来测试一下:

mydll.cpp:

#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:

#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:

#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全局变量的更多相关文章

  1. 自己封装的Socket组件,实现服务端多进程共享Socket对象,协同处理客户端请求

    DotNet.Net.MySocket是SLB.NET(Server Load Balance服务器负载均衡)项目中的核心组件. 在实际的项目中发现,单进程的服务端处理高并发的客户请求能力有限. 所以 ...

  2. 进程间通信 - 动态链接库中共享内存(利用DLL的2~3G的地址段空间)

    前言 进程是装入内存并准备执行的程序,每个进程都有私有的虚拟地址空间,由代码.数据,以及其他的一些资源组成.32位系统的进程分配4G的虚拟地址空间.内存地址范围是0x00000000-0xFFFFFF ...

  3. Nodejs中cluster模块的多进程共享数据问题

    Nodejs中cluster模块的多进程共享数据问题 前述 nodejs在v0.6.x之后增加了一个模块cluster用于实现多进程,利用child_process模块来创建和管理进程,增加程序在多核 ...

  4. 第7.12节 可共享的Python类变量

    第7.12节 可共享的Python类变量 一.    引言 在上节已经引入介绍了类变量和实例变量,类体中定义的变量为类变量,默认属于类本身,实例变量是实例方法中定义的self对象的变量,对于每个实例都 ...

  5. IPC$共享和其他共享(C$、D$)

    目录 net use共享命令的用法 IPC$ IPC空连接 ipc$使用的端口 关闭IPC$共享 net use共享命令的用法 net use #查看连接 net share              ...

  6. 在dll里malloc/new/cvCreate分配内存,在exe里free/Releases释放内存时会出错。

    写了个程序,在DLL中用malloc分配了一块内存,但是在exe程序中释放,结果程序crash,原因就是:其原因可能是堆被损坏,这也说明 TestMySticker.exe 中或它所加载的任何 DLL ...

  7. system v和posix的共享内存对比 & 共享内存位置

    参考 http://www.startos.com/linux/tips/2011012822078.html 1)Linux和所有的UNIX操作系统都允许通过共享内存在应用程序之间共享存储空间. 2 ...

  8. 多租户实现之基于Mybatis,Mycat的共享数据库,共享数据架构

    前言 SaaS模式是什么? 传统的软件模式是在开发出软件产品后,需要去客户现场进行实施,通常部署在局域网,这样开发.部署及维护的成本都是比较高的. 现在随着云服务技术的蓬勃发展,就出现了SaaS模式. ...

  9. Atitit 关于共享经济之共享男女朋友的创业计划

    Atitit 关于共享经济之共享男女朋友的创业计划 1. 共享经济的历史与趋势 1 1.1. 共享经济三大特征=产能过剩+共享平台+人人参与. 1 1.2. 共享经济是个大趋势,使用权渐渐的取代所有权 ...

随机推荐

  1. 行转列之后的datagrid的保存

    行专列之后,查询的存储过程为 1 USE [APS_Future_FT] 2 GO 3 /****** Object: StoredProcedure [dbo].[P_APS_H_InternalS ...

  2. CF400C/[思维题]

    题目链接http://codeforces.com/problemset/problem/400/C 题意:给出一个(N,M)矩形和矩形里的p(p<=1e5)个点坐标,然后顺时针旋转x,镜面对称 ...

  3. 【LYOI 212】「雅礼集训 2017 Day8」价(二分匹配+最大权闭合子图)

    「雅礼集训 2017 Day8」价 内存限制: 512 MiB时间限制: 1000 ms 输入文件: z.in输出文件: z.out   [分析] 蛤?一开始看错题了,但是也没有改,因为不会做. 一开 ...

  4. BZOJ2754 SCOI2012喵星球上的点名

    绝世好题. 正当我犹豫不决时,hzwer说:“MAP!!!” 没错这题大大的暴力,生猛的stl,贼基尔爽,,ԾㅂԾ,, 由于我们求点名在名字中的子串个数,所以将点名建AC自动机,记录节点属于哪次点名, ...

  5. 「NOI2017」游戏

    「NOI2017」游戏 题目描述 小 L 计划进行 \(n\) 场游戏,每场游戏使用一张地图,小 L 会选择一辆车在该地图上完成游戏. 小 L 的赛车有三辆,分别用大写字母 \(A\).\(B\).\ ...

  6. Codeforces 992 E. Nastya and King-Shamans

    \(>Codeforces\space992 E. Nastya and King-Shamans<\) 题目大意 : 给你一个长度为 \(n\) 的序列,有 \(q\) 次操作,每一次操 ...

  7. POJ 3162 Walking Race 树形dp 优先队列

    http://poj.org/problem?id=3162 题意 :  一棵n个节点的树.wc爱跑步,跑n天,第i天从第i个节点开始跑步,每次跑到距第i个节点最远的那个节点(产生了n个距离),现在要 ...

  8. 【manacher+FFT】BZOJ3160-万径人踪灭

    [题目大意] 在一个仅仅含有a,b的字符串里选取一个子序列,使得: 1.位置和字符都关于某条对称轴对称: 2.不能是连续的一段. [思路] 不连续的回文串的个数=总的回文串个数-连续回文串的个数. 后 ...

  9. bzoj 4769: 超级贞鱼 -- 归并排序

    4769: 超级贞鱼 Time Limit: 1 Sec  Memory Limit: 128 MB Description 马达加斯加贞鱼是一种神奇的双脚贞鱼,它们把自己的智慧写在脚上——每只贞鱼的 ...

  10. 类方法load和initialize的区别

    1.+load方法当类或分类添加到object-c runtime时被调用,子类的+load方法会在它所有父类的+load方法之后执行,而分类的+load方法会在它的主类的+load方法之后执行.但不 ...