#pragma data_seg介绍

用#pragma data_seg建立一个新的数据段并定义共享数据,其具体格式为:

  #pragma data_seg ("shareddata")

  HWND sharedwnd=NULL;//共享数据

  #pragma data_seg()   
-----------------------------------------------------------------------------------------------------

1,#pragma data_seg()一般用于DLL中。也就是说,在DLL中定义一个共享的,有名字的数据段。最关键的是:这个数据段中的全局变量可以被多个进程共享。否则多个进程之间无法共享DLL中的全局变量。

2,共享数据必须初始化,否则微软编译器会把没有初始化的数据放到.BSS段中,从而导致多个进程之间的共享行为失败。

3,你所谓的结果正确是一种错觉。如果你在一个DLL中这么写:

#pragma data_seg("MyData")

int g_Value; // Note that the global is not initialized.

#pragma data_seg()

DLL提供两个接口函数:

int GetValue()
{
      return g_Value;
}

void SetValue(int n)
{
      g_Value = n;
}

然后启动两个进程A和B,A和B都调用了这个DLL,假如A调用了SetValue(5); B接着调用int m = GetValue(); 那么m的值不一定是5,而是一个未定义的值。因为DLL中的全局数据对于每一个调用它的进程而言,是私有的,不能共享的。假如你对g_Value进行了初始化,那么g_Value就一定会被放进MyData段中。换句话说,如果A调用了SetValue(5); B接着调用int m = GetValue(); 那么m的值就一定是5!这就实现了跨进程之间的数据通信!

----------------------------------------------------------------------------------------------------
     有的时候我们可能想让一个应用程序只启动一次,就像单件模式(singleton)一样,实现的方法可能有多种,这里说说用#pragma data_seg来实现的方法,很是简洁便利。

应用程序的入口文件前面加上

#pragma data_seg("flag_data")
int app_count = 0;
#pragma data_seg()
#pragma comment(linker,"/SECTION:flag_data,RWS")

然后程序启动的地方加上

if(app_count>0)     // 如果计数大于0,则退出应用程序。
{
   //MessageBox(NULL, "已经启动一个应用程序", "Warning", MB_OK);   
   //printf("no%d application", app_count);
   return FALSE;
}
app_count++;

Windows 在一个Win32程序的地址空间周围筑了一道墙。通常,一个程序的地址空间中的数据是私有的,对别的程序而言是不可见的。但是执行STRPROG的多个执行实体表示了STRLIB在程序的所有执行实体之间共享数据是毫无问题的。当您在一个STRPROG窗口中增加或者删除一个字符串时,这种改变将立即反映在其它的窗口中。

在全部例程之间,STRLIB共享两个变量:一个字符数组和一个整数(记录已储存的有效字符串的个数)。STRLIB将这两个变量储存在共享的一个特殊内存区段中:

  1. #pragma      data_seg ("shared")         int                 iTotal = 0 ;         WCHAR               szStrings [MAX_STRINGS][MAX_LENGTH + 1] = { '/0' } ;         #pragma      data_seg ()        

第一个#pragma叙述建立数据段,这里命名为shared。您可以将这段命名为任何一个您喜欢的名字。在这里的#pragma叙述之后的所有初始化了的变量都放在shared数据段中。第二个#pragma叙述标示段的结束。对变量进行专门的初始化是很重要的,否则编译器将把它们放在普通的未初始化数据段中而不是放在shared中。

连结器必须知道有一个「shared」共享数据段。在「Project Settings」对话框选择「Link」页面卷标。选中「STRLIB」时在「Project Options」字段(在Release和Debug设定中均可),包含下面的连结叙述:

  1. /SECTION:shared,RWS        

字母RWS表示段具有读、写和共享属性。或者,您也可以直接用DLL原始码指定连结选项,就像我们在STRLIB.C那样:

  1. #pragma comment(linker,"/SECTION:shared,RWS")        

共享的内存段允许iTotal变量和szStrings字符串数组在STRLIB的所有例程之间共享。因为MAX_STRINGS等于256,而 MAX_LENGTH等于63,所以,共享内存段的长度为32,772字节-iTotal变量需要4字节,256个指针中的每一个都需要128字节。

进程共享变量#pragma data_seg用法的更多相关文章

  1. #pragma data_seg() 共享数据// MyData段 // 进程 // DLL

    https://www.cnblogs.com/dongsheng/p/4476157.html http://www.cnblogs.com/CBDoctor/archive/2013/01/26/ ...

  2. #pragma data_seg 共享数据区(转)

    原文地址:http://www.cnblogs.com/CBDoctor/archive/2013/01/26/2878201.html 1)#pragma data_seg()一般用于DLL中.也就 ...

  3. 【转】#pragma的用法

    在所有的预处理指令中,#Pragma 指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作.#pragma指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的 ...

  4. #pragma data_seg

    原文链接地址:http://www.cnblogs.com/CBDoctor/archive/2013/01/26/2878201.html 1)#pragma data_seg()一般用于DLL中. ...

  5. #pragma的用法

    在所有的预处理指令中,#Pragma   指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作.#pragma指令对每个编译器给出了一个方法,在保持与C和 C++语言完全 ...

  6. #pragma once用法总结

    1.#pragmaonce这个宏有什么作用? 为了避免同一个头文件被包含(include)多次,C/C++中有两种宏实现方式:一种是#ifndef方式:另一种是#pragma once方式. 在能够支 ...

  7. Linux 下使用 killall 命令终止进程的 8 大用法

    Linux 的命令行提供很多命令来杀死进程.比如,你可以向 kill 命传递一个PID来杀死进程:pkill 命令使用一个正则表达式作为输入,所以和该模式匹配的进程都被杀死. 但是还有一个命令叫 ki ...

  8. #pragma 的用法

    它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作.#pragma指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的情况下,给出主机或操作系统专有的特征.依据定义,编译指示是机 ...

  9. #pragma pack()用法详解

    博客转载自:http://blog.csdn.net/lime1991/article/details/44536343 1.什么是对齐?为什么要对齐? 现代计算机中内存空间都是按照byte划分的,从 ...

随机推荐

  1. mybatis自学历程(一)

    第一个mybatis程序 IDE:myeclipse2017 jar包:mybatis3.5.2,mybatis依赖包,mysql8.0.17驱动包 注:mybatis包和所需的依赖包,可到http: ...

  2. IDEA中将工程打包成war包及部署到Tomcat流程

    工程打包成war包及部署到Tomcat流程 再IDEA开发工具中,将工程打包成war包流程: 父pom里需要移除内置的tomcat <dependency> <groupId> ...

  3. enovia PLM : add new value to SPEO

    Solution: Modify LUX_SPEO attribute in PLM Modify D_SPEO attribute in SAP , Login sap system F3 Tcod ...

  4. MNIST多图显示--Python练习

    在学习TensorFlow框架时,提到用MNIST手写数字数据库进行练习,为了更直观看下里面的数据到底长啥样,用OpenCV(cv2)中的imshow函数来进行显示. 默认已经安装: numpy.te ...

  5. c# DataTable第二行改为各列标题字段

    DataTable dt = ExcelHelper.ToDataTable(fileinfo.FilePath); //将datatable的第二行变为列标题字段 DataTable dt2 = n ...

  6. Eclipse如何设置jsp文件默认UTF-8格式编码

    我使用的是Eclipse Jee Neon, Window->Preferences 具体设置如图所示: 

  7. 36.两个链表的第一个公共结点(python)

    题目描述 输入两个链表,找出它们的第一个公共结点. class Solution: def FindFirstCommonNode(self, pHead1, pHead2): # write cod ...

  8. k8s集群的搭建之三:flannel

    一介绍 flannel是CoreOS提供用于解决Dokcer集群跨主机通讯的覆盖网络工具.它的主要思路是:预先留出一个网段,每个主机使用其中一部分,然后每个容器被分配不同的ip:让所有的容器认为大家在 ...

  9. JavaSE---枚举

    1.概述 1.1 某些情况下,一个类的对象是  有限且固定的,eg:四季... 1.2 手动实现枚举类: 1.1.1 私有化构造器 1.1.2 将类的属性用private final修饰: 将类的实例 ...

  10. CleanMyMac x如何关闭自动更新,CleanMyMac关闭自动更新的方法

    在众多Mac清理软件中,CleanMyMac x应该是大多数Mac用户的选择,因为它不仅可以帮助我们清理系统垃圾,还可以帮助我们彻底卸载Mac上不需要的应用程序.今天要给大家介绍的是CleanMyMa ...