3.6.2 使用DLL通信的方法 从上面可以看出,对于Win32的DLL,所有载入DLL的应用程序只能共享程序代码,不能共享数据,必须要采取一种方法才能使这些程序之间共享数据。当然访问数据时要注意同步问题。 要想使Win32 DLL的数据区能设计成共享的存储区,可以通过#pragma data_seg指令建立一个新段来做到这一点,实际上是告诉编译器包含段中的特定变量。然而,仅此不足以做到数据共享,还必须把段中将要共享的变量告诉连接器。可通过如下命令来 实现: (1)指定DEF文件在SECTIONS段下的名字,如下所示: SECTIONS 共享段名 READ WRITE SHARED (2)#pragma comment(linker,"/SECTION: 共享段名,RWS") 下面的例子示范了如何初始化一个全局变量: #pragma data_seg("MyShared") UINT m_glnData=0; #pragma data_seg() #pragma comment(linker,"/SECTION:MyShared,RWS") 注意要初始化变量。初始化变量很重要,因为编译器将把所有未初始化数据存放在.bss段。把变量安排在与用户预期不同的段中,则它们就不能被共享,除非明确地指出要共享的是.bss段。 关于共享数据段名称MyShared,完全可以用其他的名称,如MYDATA、.MYSC等,但建议不要与PE文件的固定的段名相同,以免程序运行时出错。 最后一点要强调的是,进行通信的程序要使用同一个DLL文件。如果使用的是相同DLL文件的不同副本,则不能实现进程之间的通信。 3.6.3 使用DLL通信的实例 与前面所讲的通信方法不同,本实例使用DLL实现进程间的通信。以下是一个用于生成DLL文件的头文件DllObj.h。其具体代码如下: // DllObj.h:头文件 // #ifndef _DLLOBJ_H_INCLUDED #define _DLLOBJ_H_INCLUDED #include #ifdef _cplusplus #define _DLLCOM_ extern "C" _declspec (dllexport) #else #define _DLLCOM_ _declspec (dllexport) #endif _DLLCOM_LPSTR GetValueString(); _DLLCOM_void SetValueString(LPCSTR str); #endif 其中SetValueString()和GetValueString()函数分别用于向所指定的共享存储区里写入和读取字符串。_DLLCOM_ 用于定义DLL中函数的输出。可以看出,SetValueString()和GetValueString()函数的写法与其他DLL文件的写法没有什么不同。但是,这两个函数所用到的共用字符串变量m_strString的表示方法则是用DLL实现内存数据共享的关键。 现在来看看如何制作一个这样的DLL文件。先用MFCAppWizard(dll)生成一个dllcom 模板(可以取其他的名称),然后把以下的代码包含在一个dllcom.cpp文件中,再用VC++编译器进行编译和连接,就可以生成dllcom.dll和dllcom.lib文件。生成这个DLL文件的核心代码如下: #pragma data_seg("MyShared") char m_strString[256]=TEXT(""); volatile bool bInCriticalSection=FALSE; #pragma data_seg() #pragma comment(linker,"/SECTION:MyShared,RWS") CCriticalSection cs; // 从内存中读取字符串 _DLLCOM_ LPSTR GetValueString() { while(bInCriticalSection) // 等待 Sleep(1); returnm_strString; } // 把字符串存储到共享内存中 _DLLCOM_ void SetValueString(LPCSTR str) { while(bInCriticalSection) // 等待 Sleep(1); cs.Lock(); bInCriticalSection = TRUE; strcpy(m_strString,str); bInCriticalSection = FALSE; cs.Unlock(); } 其中bInCriticalSection为进程访问数据时的同步标识。 在制作了一个用于进程间通信的DLL文件后,就可以利用它实现进程之间的通信。可以设计两个应用程序,dlluser1和dlluser2,在这两个程序中把动态库文件头DllObj.h和动态库dllcom.lib包含其中,即 #include "DllObj.h" #pragma comment(lib,"dllcom.lib") 然后,用MFCVC++编译器进行编译和连接,这样就可以用SetValueString()和GetValue-String()函数进行通信了。
dll实现进程通信
关注
打赏