#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将这两个变量储存在共享的一个特殊内存区段中:

#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设定中均可),包含下面的连结叙述:

/SECTION:shared,RWS        

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

#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. SQL 测验题目(30道)

    1.SQL 指的是? 您的回答:Structured Query Language 2.哪个 SQL 语句用于从数据库中提取数据? 您的回答:SELECT 3.哪条 SQL 语句用于更新数据库中的数据 ...

  2. A + B Problem II HDU - 1002

    非常简单的大数加法,因为不会Java只能手写大数加法了;博客存一下以后回来看看 #include<bits/stdc++.h> using namespace std; +; char A ...

  3. git的使用(本地版本库)

    1. 创建版本库 1.1 创建一个版本库非常简单,首先,选择一个合适的地方,创建一个空目录: 1.2通过git init命令把这个目录变成Git可以管理的仓库(git进入空目录的路径) $ git i ...

  4. Windows XP 下如何使用Qt Creator中的Git版本控制功能

     原文地址:http://www.qtcn.org/bbs/simple/?t16960.html Qt Creator是针对Qt应用开发平台专门设计的IDE开发工具,集成了很多功能,分别有win ...

  5. Kotlin 和 Flutter 对于开发者究竟意味着什么?

    更多阿里P7架构进阶学习视频:阿里P7Android架构进阶学习视频回放近些年来,编程语言流行度的变化其实不大,在 TIOBE 编程语言排行榜上,Java.C.C++ 固若金山,也就只有 Python ...

  6. cordova插件值 二维码扫描

    插件地址 https://github.com/gizwits/cordova-gizwits-scan-qrcode 插件安装方式 cordova plugin add https://github ...

  7. Java web 应用自启动 shell脚本自动重启

    之前公司的内部管理系统jenkins自动构建代码有时候会失效,导致服务停掉. 于是乎就搞了一个自动启动脚本. oa.jar就是监测的服务 startup.sh 的内容是运行jar包的命令 java - ...

  8. Eclipse导入的Maven项目没有Build Path

    我导入的是 Signal-Server项目到 Eclipse中,发现 src 文件夹上面没有#号,包视图和语法提示都没有 ~~ 解决方法: 修改 Project Facets 在 项目右键 -> ...

  9. 2017 ACM/ICPC Asia Regional Shenyang Online 12 card card card

    题目大意: 给出两个长度为n的序列A,B,从1开始依次加Ai,减Bi,分数为第一次为当前和为负数的位置以前的Ai之和(左闭右开区间).同时有一种操作可以把当前的A1,B1移动到序列最后,注意序列A的各 ...

  10. spring.xml及注解

    spring.xml配置文件中配置注解: 开启注解(及自动扫描包中bean): 1:<context:component-scan base-package="com.bzu" ...