使用DLL在进程间共享数据
0x01 DLL在进程间共享数据理论
1.可以在Dll中使用#pragma data_seg建立共享类型的数据段将需要共享的数据分离出来,放置在一个独立的数据段里,并把该段的属性设置为共享,从而实现不同进程的数据共享。并且必须给这些变量赋初值,否则编译器会把没有赋初始值的变量放在一个叫未被初始化的数据段中。
1 2 3 4 | #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 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗