使用DLL在进程间共享数据
0x01 DLL在进程间共享数据理论
1.可以在Dll中使用#pragma data_seg建立共享类型的数据段将需要共享的数据分离出来,放置在一个独立的数据段里,并把该段的属性设置为共享,从而实现不同进程的数据共享。并且必须给这些变量赋初值,否则编译器会把没有赋初始值的变量放在一个叫未被初始化的数据段中。
#pragma data_seg("SHARED") //建立数据段,这里命名为SHARED char __ShareData[MAX_PATH] = "我是共享数据型蜻蜓队长 OVER~(dll)"; //对变量进行专门的初始化是必需的,否则编译器将把它们放在普通的未初始化数据段中而不是放在shared中,那样的话就无法实现共享数据了 #pragma data_seg() //标示段的结束 #pragma comment(linker,"/SECTION:SHARED,RWS") //指定链接选项 //RWS表示段具有读、写和共享属性
2.函数导出方式 extern "C" __declspec(dllexport) 和 _declspec(dllexport) 的区别
使用extern "C" __declspec(dllexport)声明导出函数,在DLL中的函数名字保持与导出函数名一致。使用__declspec(dllexport)声明导出函数,在DLL中的函数名字与导出函数名字不一致,有变化。这些差异主要是使用C方式函数C++方式编译导致的。
所以,在使用GetProcAddress( HMODULE hModule, LPCWSTR lpProcName)函数查找导出函数时,最好在DLL中用extern "C" __declspec(dllexport)声明导出函数。
_declspec(dllexport)导出方式的函数名:
extern "C" __declspec(dllexport) 导出方式对比:
0x02 程序结果和源代码
共享段数据被Test1进程修改后被test2进程读取到:
源代码:
1 // Dll.cpp : 定义 DLL 应用程序的导出函数。 2 // 3 4 #include "stdafx.h" 5 #include <iostream> 6 #include <windows.h> 7 using namespace std; 8 9 char __BufferData[MAX_PATH] = "我是蜻蜓队长 OVER~(dll)"; 10 11 12 #pragma data_seg("SHARED") //建立数据段,这里命名为SHARED 13 char __ShareData[MAX_PATH] = "我是共享数据型蜻蜓队长 OVER~(dll)"; //对变量进行专门的初始化是必需的,否则编译器将把它们放在普通的未初始化数据段中而不是放在shared中,那样的话就无法实现共享数据了 14 #pragma data_seg() //标示段的结束 15 #pragma comment(linker,"/SECTION:SHARED,RWS") //指定链接选项 //RWS表示段具有读、写和共享属性 16 17 18 19 extern CRITICAL_SECTION __CriticalSection; 20 _declspec(dllexport) 21 char* GetBufferData() 22 { 23 return __BufferData; 24 } 25 26 _declspec(dllexport) 27 void SetBufferData(char* BufferData,int BufferLength) 28 { 29 __try 30 { 31 memcpy(__BufferData, BufferData, BufferLength); 32 } 33 __except (EXCEPTION_EXECUTE_HANDLER) 34 { 35 printf("异常\r\n"); 36 37 return; 38 } 39 } 40 41 //声明为导出函数 42 _declspec(dllexport) 43 char* GetShareData() 44 { 45 return __ShareData; 46 } 47 48 _declspec(dllexport) 49 void SetShareData(char* BufferData, int BufferLength) 50 { 51 52 53 EnterCriticalSection(&__CriticalSection); 54 __try 55 { 56 memcpy(__ShareData, BufferData, BufferLength); 57 } 58 __except (EXCEPTION_EXECUTE_HANDLER) 59 { 60 61 printf("异常\r\n"); 62 } 63 64 LeaveCriticalSection(&__CriticalSection); 65 return; 66 } 67 68 69 extern "C" __declspec (dllexport) 70 void Sub_1() 71 { 72 73 } 74 _declspec(dllexport) 75 void Sub_2() 76 { 77 78 }