#pragma data_seg("flag_data")
int count=0;
#pragma data_seg()
#pragma comment(linker,"/SECTION:flag_data,RWS")
这种方法只能在没有def文件时使用,如果通过def文件进行导出的话,那么设置就要在def文件内设置而不能
在代码里设置了。
SETCTIONS
flag_data READ WRITE SHARED
在主文件中,用#pragma data_seg建立一
个新的数据段并定义共享数据,其具体格式为:
#pragma data_seg ("shareddata") //名称可以
//自己定义,但必须与下面的一致。
HWND sharedwnd=NULL;//共享数据
#pragma data_seg()
仅定义一个数据段还不能达到共享数据的目的,还要告诉编译器该段的属性,有两种方法可以实现该目的 (其效果是相同的),一种方法是在.DEF文件中加入如下语句: SETCTIONS shareddata READ WRITE SHARED 另一种方法是在项目设置链接选项(Project Setting --〉Link)中加入如下语句: /SECTION:shareddata,rws
第一点:什么是共享数据段?为什么要用共享数据段??它有什么用途??
在Win16环境中,DLL的全局数据对每个载入它的进程来说都是相同的;而在Win32环境中,情况却发生了变化,DLL函数中的代码所创建的任何对象(包括变量)都归调用它的线程或进程所有。当进程在载入DLL时,操作系统自动把DLL地址映射到该进程的私有空间,也就是进程的虚拟地址空间,而且也复制该DLL的全局数据的一份拷贝到该进程空间。也就是说每个进程所拥有的相同的DLL的全局数据,它们的名称相同,但其值却并不一定是相同的,而且是互不干涉的。
因此,在Win32环境下要想在多个进程中共享数据,就必须进行必要的设置。在访问同一个Dll的各进程之间共享存储器是通过存储器映射文件技术实现的。也可以把这些需要共享的数据分离出来,放置在一个独立的数据段里,并把该段的属性设置为共享。必须给这些变量赋初值,否则编译器会把没有赋初始值的变量放在一个叫未被初始化的数据段中。
#pragma data_seg预处理指令用于设置共享数据段。例如:
#pragma data_seg("SharedDataName") HHOOK hHook=NULL; //必须在定义的同时进行初始化!!!!#pragma data_seg()
在#pragma data_seg("SharedDataName")和#pragma data_seg()之间的所有变量将被访问该Dll的所有进程看到和共享。再加上一条指令#pragma comment(linker,"/section:.SharedDataName,rws"),[注意:数据节的名称is case sensitive]那么这个数据节中的数据可以在所有DLL的实例之间共享。所有对这些数据的操作都针对同一个实例的,而不是在每个进程的地址空间中都有一份。
当进程隐式或显式调用一个动态库里的函数时,系统都要把这个动态库映射到这个进程的虚拟地址空间里(以下简称"地址空间")。这使得DLL成为进程的一部分,以这个进程的身份执行,使用这个进程的堆栈。(这项技术又叫code Injection技术,被广泛地应用在了病毒、黑客领域!呵呵^_^)
第二点:在具体使用共享数据段时需要注意的一些问题!
Win32 DLLs are mapped into the address space of the calling process. By default, each process using a DLL has its own instance of all the DLLs global and static variables. (注意: 即使是全局变量和静态变量也都不是共享的!) If your DLL needs to share data with other instances of it loaded by other applications, you can use either of the following approaches:
· Create named data sections using the data_seg pragma.
· Use memory mapped files. See the Win32 documentation about memory mapped files.
Here is an example of using the data_seg pragma:
#pragma data_seg (".myseg")
int i = 0;
char a[32] = "hello world";
#pragma data_seg()
data_seg can be used to create a new named section (.myseg in this example). The most typical usage is to call the data segment .shared for clarity. You then must specify the correct sharing attributes for this new named data section in your .def file or with the linker option /SECTION:.MYSEC,RWS. (这个编译参数既可以使用pragma指令来指定,也可以在VC的IDE中指定!)
There are restrictions to consider before using a shared data segment:
· Any variables in a shared data segment must be statically initialized. In the above example, i is initialized to 0 and a is 32 characters initialized to hello world.
· All shared variables are placed in the compiled DLL in the specified data segment. Very large arrays can result in very large DLLs. This is true of all initialized global variables.
· Never store process-specific information in a shared data segment. Most Win32 data structures or values (such as HANDLEs) are really valid only within the context of a single process.
· Each process gets its own address space. It is very important that pointers are never stored in a variable contained in a shared data segment. A pointer might be perfectly valid in one application but not in another.
· It is possible that the DLL itself could get loaded at a different address in the virtual address spaces of each process. It is not safe to have pointers to functions in the DLL or to other shared variables.
分享到:
相关推荐
`#pragma data_seg`是C/C++预处理器的一个指令,用于设置数据段的位置,它可以帮助我们在内存中创建共享的数据区域,从而实现多个进程间的通信。 在标题“利用pragma data_seg实现程序只能单个实例运行”中,关键点...
10. **data_seg**:指定已初始化的全局变量所在的段。 11. **code_seg**:指定代码段的位置。 12. **const_seg**:指定常量段的位置。 13. **check_stack**:启用栈检查。 14. **function**:指定函数属性。 15. **...
此指令用于指定在DLL或其它动态链接库中的初始化变量应该位于对象文件的哪个数据段中。正确使用data_seg可以帮助程序员更好地控制内存的分配和程序的链接行为。 ## 知识点三:#pragma使用注意事项 - #pragma指令在...
这通常与`#pragma code_seg`, `const_seg`, `data_seg`, `section`, `init_seg`等配合使用,定义代码或数据存储区域。例如,如果你希望某些变量在共享数据段中,你可以这样声明: ```cpp #pragma data_seg("share...
在Visual C++中,可以通过预处理器指令`#pragma data_seg`来定义共享数据段。例如: ```cpp #pragma data_seg("shareddata") HWND sharedwnd = NULL; // 共享窗口句柄 #pragma data_seg() ``` 此外,还需要在`.DEF...
- `#pragma data_seg("shared")` 和 `#pragma comment(linker, "/SECTION:shared,RWS")`:这两行是为了让`counter`变量可以在不同的应用程序间共享。 - `DllMain`函数:这是DLL的入口点,用于初始化和清理DLL资源...
#pragma dataseg(".global") int A_Public_Number = 0; #pragma dataseg(".local") int A_Private_Number = 0; #pragma dataseg("") 但是在共享数据段内的变量必须初始化,如上面的A_Public_Number=0;如果没有初始 ...
这个关键字允许将变量声明为在特定数据段中存储,与`#pragma code_seg`, `#pragma const_seg`, `#pragma data_seg`, `#pragma section`, `#pragma init_seg`等配合使用。例如,`__declspec(allocate("share_data"))...
#pragma data_seg("TestData") HWND glhPrevTarWnd = NULL; // 上一次的目标窗口 HWND glhHook = NULL; // 钩子句柄 HINSTANCE glhInstance = NULL; // DLL实例句柄 #pragma data_seg() typedef struct _...
文档中提到了“#pragma data_seg”,这是一种编译器指令,用于声明一个全局共享的数据段。在钩子编程中,多个进程或线程可能需要访问同一个共享的数据,使用这个指令可以方便实现数据共享。 8. Windows消息处理 ...
例如,使用`#pragma data_seg`指定内存段,并使用`volatile`关键字确保多线程环境中的可见性,以及使用`std::mutex`进行同步。 8. **进程崩溃排查**: 如果目标进程无法启动,首先要检查它能否单独运行,然后再...
格式为 __declspec(allocate("segname")) declarator,其中 segname 是数据段名,必须是以下列举中的一个:code_seg、const_seg、data_seg、init_seg、section。 3. appdomain:用于指定托管程序中的每个应用程序域...
两个#pragma data_seg()编译器指令是为了定义一个名为.MouseHook的数据段(更确切地说是数据节),该数据段在MouseHook.DEF中被说明为共享,之所以如此是因为各个进程空间中的MouseProc()需要该钩子的句柄hMouseHook,...
/*以下创建一共享段实现进程间的数据通讯, szAccountName 是用户名,bPrepared说明 szAccountName是否已初始化。*/ #pragma data_seg(".MYSHARE") BOOL bPrepared=FALSE; wchar_t szAccountName[100]={0}; #...
#define C_DATA66 0x00000008 #define C_DATA1 0x00000010 #define C_DATA2 0x00000020 #define C_DATA4 0x00000040 #define C_MEM67 0x00000080 #define C_MEM1 0x00000100 #define C_MEM2 0x00000200 #define C_...
/*以下创建一共享段实现进程间的数据通讯, szAccountName 是用户名,bPrepared说明 szAccountName是否已初始化。*/ #pragma data_seg(".MYSHARE") BOOL bPrepared=FALSE; wchar_t szAccountName[100]={0}; #pragma...