#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. Java学习之构造函数

    构造函数特点:  函数名和类名相同  没有返回值(不用定义返回值类型)作用:  对象初始化注意:  如果类没有定义构造函数时,系统会默认定义一个无参的构造函数  如果定义了构造函数,系统不会定义构造函 ...

  2. windbg show args after breakpoint

    bp ntdll!NtOpenFile ".echo ####################;du poi(ebp+8);.echo ########################;&q ...

  3. Rust <1>:数据类型、变量、可变性、常量、隐藏

    rust 是强类型语言,所有变量.常量都必须有明确的数据类型:很多情况下,省略类型声明,编译器可自动推导,但不是所有情况下都会成功. rust 有整型.浮点型.布尔型.字符型.数组.元组.枚举.结构体 ...

  4. vue轮播,展示pdf

    vue轮播,展示pdf 根据左侧图片格式,右侧展示相应的pdf文件与图片.(vue中不支持pdf格式,pdf文件要放在static文件里):代码如下: <template> <!-- ...

  5. Struts2的Action访问

    ● 示例项目结构 ●  demo1.jsp <%@ page language="java" import="java.util.*" pageEncod ...

  6. 数据结构与算法简记--redis有序集合实现-跳跃表

    跳表 定义 为一个值有序的链表建立多级索引,比如每2个节点提取一个节点到上一级,我们把抽出来的那一级叫做索引或索引层.如下图所示,其中down表示down指针,指向下一级节点.以此类推,对于节点数为n ...

  7. ActionEnter cannot be resolved to a type

    2014-6-13 23:50:57 org.apache.catalina.core.StandardWrapperValve invoke严重: Servlet.service() for ser ...

  8. ollvm 编译

    ollvm 的编译相对 llvm 更简单, 1:下载ollvm代码,去 https://github.com/obfuscator-llvm/obfuscator/tree/llvm-4.0 下载,并 ...

  9. java多线程面试题_线程并发面试题

    1.什么是线程?线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.程序员可以通过它进行多处理器编程,你可以使用多线程对运算密集型任务提速.比如,如果一个线程完成一个 ...

  10. propTypes和 defaultProps

    propTypes和 defaultProps propTypes: 可以 用来做类型的校验 限制类型 isRequired 必须要求传递 要使用必须先引入: import PropTypes fro ...