在DLL中共享內存實(shí)際上是一個(gè)內存映射文件在起作用。Windows為每一個(gè)進(jìn)程空間分配一個(gè)私有的地址空間,所以對于一個(gè)進(jìn)程而言,其他進(jìn)程的數據是不可見(jiàn)的。但如果在DLL中使用了共享內存,那么這一塊內存中的數據對于所有調用它的實(shí)例都是可見(jiàn)的,也就是說(shuō)實(shí)現了數據共享。
下面通過(guò)介紹一個(gè)實(shí)例“ShareRam”來(lái)看DLL共享內存是如何實(shí)現的。在實(shí)例中定義了用于共享的兩個(gè)變量:一個(gè)整數和一個(gè)字符串數組。整數用于記錄保存在字符串數組中的有效字符串個(gè)數,字符串數組用于保存輸入的有效字符串。運用了標準C的指令#pragma,為這兩個(gè)變量分配特殊的內存段用于共享。
- 在分配完特殊的內存段后進(jìn)行鏈接時(shí),鏈接程序必須知道有一個(gè)用于共享的share段。使用以下方法可以通知鏈接程序,其中RWS表示具有讀、寫(xiě)和共享的屬性:
- #pragma data_seg ("shared")
- int iTotal=0 ;
- WCHAR szStrings [MAX_STRINGS][MAX_LENGTH 1]={ '\0' } ;
- #pragma data_seg ()
-
復制代碼- 當然也可以在“Project Setting”對話(huà)框的“Link”選項卡中,選中ShareLib時(shí),在Project Options域中包含下面的鏈接語(yǔ)句:
- #pragma comment(linker,"/SECTION:shared,RWS")
復制代碼- 從以上的定義可以得出,所有調用ShareLib的應用程序的實(shí)例共享的數據為:iTotal和szStrings。用于存儲數據的內存大小可以計算得出:iTotal需要4字節,szStrings需要64?32?2字節,一共需要約4 100字節。
- /SECTION:shared,RWS
復制代碼 用于共享內存的動(dòng)態(tài)鏈接庫的核心代碼如下:- [/font][size=10][font=宋體]至此,已經(jīng)看到了運用共享內存段在多個(gè)應用程序共享數據的方法。但在這個(gè)實(shí)例中用到的共享內存段的空間是提前分配好的,在實(shí)際應用中這種方法有較大的限制。在實(shí)際的運用中可以采用動(dòng)態(tài)分配共享內存空間的方法,這就要用到第[/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=宋體]個(gè)字符串[/font]
- #define MAX_LENGTH 32 // [font=宋體]定義字符串長(cháng)度不能超過(guò)[/font]32?2[font=宋體]字節[/font]
-
- // [font=宋體]預定義一個(gè)用于回調的函數[/font]GETSTRCB[font=宋體],它含[/font]PCTSTR[font=宋體]和[/font]PVOID[font=宋體]兩個(gè)參數[/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=宋體]用于將從對話(huà)框中接收到的字符串存儲到共享內存中[/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;
}
// 將刪除的字符串之后的字符串在數組中的位置分別向前移,數組內數據的個(gè)
// 數減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 )
{
// 調用在應用程序內定義的回調函數,在客戶(hù)區顯示字符串數組中的
// 內容
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:
// 調用對話(huà)框用于接收輸入到共享內存的字符串
if (DialogBox(hInst, TEXT ("EnterDlg"), hWnd, &DlgProc))
{
if (AddString ((PCWSTR) szString))
// 發(fā)送消息用于刷新客戶(hù)區
PostMessage(HWND_BROADCAST, iDataChangeMsg, 0, 0);
else
MessageBeep(0);
}
break ;
case IDM_DELETE:
// 調用對話(huà)框用于接收需要從共享內存中刪除的字符串
if(DialogBox(hInst, TEXT("DeleteDlg"), hWnd, &DlgProc))
{
if(DeleteString((PCWSTR) szString))
// 發(fā)送消息用于刷新客戶(hù)區
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 ;
………………………………
}
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請
點(diǎn)擊舉報。