在DLL中共享内存实际上是一个内存映射文件在起作用。Windows为每一个进程空间分配一个私有的地址空间,所以对于一个进程而言,其他进程的数据是不可见的。但如果在DLL中使用了共享内存,那么这一块内存中的数据对于所有调用它的实例都是可见的,也就是说实现了数据共享。
下面通过介绍一个实例“ShareRam”来看DLL共享内存是如何实现的。在实例中定义了用于共享的两个变量:一个整数和一个字符串数组。整数用于记录保存在字符串数组中的有效字符串个数,字符串数组用于保存输入的有效字符串。运用了标准C的指令#pragma,为这两个变量分配特殊的内存段用于共享。
- 在分配完特殊的内存段后进行链接时,链接程序必须知道有一个用于共享的share段。使用以下方法可以通知链接程序,其中RWS表示具有读、写和共享的属性:
- #pragma data_seg ("shared")
- int iTotal=0 ;
- WCHAR szStrings [MAX_STRINGS][MAX_LENGTH 1]={ '\0' } ;
- #pragma data_seg ()
-
复制代码- 当然也可以在“Project Setting”对话框的“Link”选项卡中,选中ShareLib时,在Project Options域中包含下面的链接语句:
- #pragma comment(linker,"/SECTION:shared,RWS")
复制代码- 从以上的定义可以得出,所有调用ShareLib的应用程序的实例共享的数据为:iTotal和szStrings。用于存储数据的内存大小可以计算得出:iTotal需要4字节,szStrings需要64?32?2字节,一共需要约4 100字节。
- /SECTION:shared,RWS
复制代码 用于共享内存的动态链接库的核心代码如下:- [/font][size=10][font=宋体]至此,已经看到了运用共享内存段在多个应用程序共享数据的方法。但在这个实例中用到的共享内存段的空间是提前分配好的,在实际应用中这种方法有较大的限制。在实际的运用中可以采用动态分配共享内存空间的方法,这就要用到第[/font][/size][size=10][font=times new roman]8[/font][/size][size=10][font=宋体]章介绍的对象映射文件。[/font][/size][size=10][font=times new roman] [/font][/size]
- /*
- ----------------------------------------------
- // ShareLib.h
- ----------------------------------------------
- */
- #include <stdlib.h>
- #include <malloc.h>
- #include <windows.h>
- #include <wchar.h> // for wide-character string functions
-
- #ifdef __cplusplus
- #define EXPORT extern "C" __declspec (dllexport)
- #else
- #define EXPORT __declspec (dllexport)
- #endif
-
- #define MAX_STRINGS 64 // [font=宋体]定义在[/font]DLL[font=宋体]中最多可以存储[/font]64[font=宋体]个字符串[/font]
- #define MAX_LENGTH 32 // [font=宋体]定义字符串长度不能超过[/font]32?2[font=宋体]字节[/font]
-
- // [font=宋体]预定义一个用于回调的函数[/font]GETSTRCB[font=宋体],它含[/font]PCTSTR[font=宋体]和[/font]PVOID[font=宋体]两个参数[/font]
- typedef BOOL (CALLBACK * GETSTRCB) (PCTSTR, PVOID) ;
-
- EXPORT BOOL CALLBACK AddString (PCWSTR) ;
- EXPORT BOOL CALLBACK DeleteString (PCWSTR) ;
- EXPORT int CALLBACK GetStrings (GETSTRCB, PVOID) ;
-
- /*
- ----------------------------------------------
- // ShareLib.c
- ----------------------------------------------
- */
- #include "sharelib.h"
-
- #pragma data_seg ("shared")
- int iTotal=0 ;
- WCHAR szStrings [MAX_STRINGS][MAX_LENGTH 1]={ '\0' };
- #pragma data_seg ()
-
- #pragma comment(linker,"/SECTION:shared,RWS")
-
- int WINAPI DllMain (HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved)
- {
- return TRUE;
- }
-
- // [font=宋体]用于将从对话框中接收到的字符串存储到共享内存中[/font]
- EXPORT BOOL CALLBACK AddString (PCWSTR pStringIn)
- {
- PWSTR pString;
- int i, iLength;
-
- if (iTotal == MAX_STRINGS - 1)
- return FALSE;
-
- if ((iLength=wcslen (pStringIn)) == 0)
- {
- MessageBox( NULL, "Please Input Number Or Char", "No Input ",
- MB_OK | MB_ICONINFORMATION);
- return FALSE ;
- }
-
- // [font=宋体]将接收的字符串拷贝到定义的私有字符串中[/font]
- pString=malloc (sizeof (WCHAR) * (1 iLength));
- wcscpy (pString, pStringIn);
-
- // [font=宋体]将要添加的字符串添加到字符串数组[/font]
- wcscpy (szStrings[iTotal ], pString);
-
-
- free (pString);
- return TRUE;
- }
-
复制代码 EXPORT BOOL CALLBACK DeleteString (PCWSTR pStringIn)
{
int i, j;
if (0 == wcslen (pStringIn))
{
MessageBox( NULL, "lease Input Number Or Char to Delete", "No Input ",
MB_OK | MB_ICONINFORMATION);
return FALSE;
}
// 在字符串数组中查找要删除的字符串
for (i=0 ; i < iTotal ; i )
{
if (_wcsicmp (szStrings, pStringIn) == 0)
break ;
}
// 如果不存在,显示提示信息
if (i == iTotal)
{
MessageBox(NULL, "No Found the Input Number Or Char to Delete",
"No Match ", MB_OK | MB_ICONINFORMATION);
return FALSE;
}
// 将删除的字符串之后的字符串在数组中的位置分别向前移,数组内数据的个
// 数减1
for (j=i ; j < iTotal ; j )
wcscpy (szStrings[j], szStrings[j 1] );
szStrings[iTotal--][0]='\0';
return TRUE;
}
EXPORT int CALLBACK GetStrings (GETSTRCB pfnGetStrCallBack, PVOID pParam)
{
BOOL bReturn;
int i;
for (i=0 ; i < iTotal ; i )
{
// 调用在应用程序内定义的回调函数,在客户区显示字符串数组中的
// 内容
bReturn=pfnGetStrCallBack (szStrings, pParam);
if (bReturn == FALSE)
return i 1;
}
return iTotal;
}
/*
---------------------------------------------
// ShareTest.h
---------------------------------------------
*/
#include <windows.h>
…………………………………………………………
typedef struct
{
HDC hdc ; int xText ; int yText ; int xStart ; int yStart ;
int xIncr ; int yIncr ; int xMax ; int yMax ; } CBPARAM ;
……………………………………………………………
/*
------------------------------------------
// ShareTest.c
------------------------------------------
*/
#include "ShareTest.h"
#include "Sharelib.h"
………………………………………………
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg,
WPARAM wParam, LPARAM lParam)
{
static HINSTANCE hInst ;
static int cxChar, cyChar, cxClient, cyClient;
static UINT iDataChangeMsg ;
CBPARAM cbparam;
HDC hdc ;
PAINTSTRUCT ps;
TEXTMETRIC tm;
switch (uMsg)
{
………………………………………
case WM_COMMAND:
switch(wParam)
{
case IDM_ENTER:
// 调用对话框用于接收输入到共享内存的字符串
if (DialogBox(hInst, TEXT ("EnterDlg"), hWnd, &DlgProc))
{
if (AddString ((PCWSTR) szString))
// 发送消息用于刷新客户区
PostMessage(HWND_BROADCAST, iDataChangeMsg, 0, 0);
else
MessageBeep(0);
}
break ;
case IDM_DELETE:
// 调用对话框用于接收需要从共享内存中删除的字符串
if(DialogBox(hInst, TEXT("DeleteDlg"), hWnd, &DlgProc))
{
if(DeleteString((PCWSTR) szString))
// 发送消息用于刷新客户区
PostMessage(HWND_BROADCAST, iDataChangeMsg,0, 0);
else
MessageBeep(0);
}
break;
………………………
}
return 0 ;
………………………
case WM_PAINT:
hdc=BeginPaint(hWnd, &ps);
cbparam.hdc =hdc;
cbparam.xText=cbparam.xStart=cxChar;
cbparam.yText=cbparam.yStart=cyChar;
cbparam.xIncr=cxChar * MAX_LENGTH;
cbparam.yIncr=cyChar;
cbparam.xMax=cbparam.xIncr *(1 cxClient / cbparam.xIncr);
cbparam.yMax=cyChar *(cyClient / cyChar - 1);
// 用于显示在共享内存中的字符串数组的值
GetStrings((GETSTRCB) GetStrCallBack, (PVOID) &cbparam);
EndPaint(hWnd, &ps);
return 0 ;
………………………………
}
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请
点击举报。