打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
DLL中的共享内存(实例)
在DLL中共享内存实际上是一个内存映射文件在起作用。Windows为每一个进程空间分配一个私有的地址空间,所以对于一个进程而言,其他进程的数据是不可见的。但如果在DLL中使用了共享内存,那么这一块内存中的数据对于所有调用它的实例都是可见的,也就是说实现了数据共享。
   下面通过介绍一个实例“ShareRam”来看DLL共享内存是如何实现的。在实例中定义了用于共享的两个变量:一个整数和一个字符串数组。整数用于记录保存在字符串数组中的有效字符串个数,字符串数组用于保存输入的有效字符串。运用了标准C的指令#pragma,为这两个变量分配特殊的内存段用于共享。
  1. 在分配完特殊的内存段后进行链接时,链接程序必须知道有一个用于共享的share段。使用以下方法可以通知链接程序,其中RWS表示具有读、写和共享的属性:
  2. #pragma data_seg ("shared")
  3. int iTotal=0 ;
  4. WCHAR szStrings [MAX_STRINGS][MAX_LENGTH 1]={ '\0' } ;
  5. #pragma data_seg ()
  6.    
复制代码
  1.     当然也可以在“Project Setting”对话框的“Link”选项卡中,选中ShareLib时,在Project Options域中包含下面的链接语句:
  2. #pragma comment(linker,"/SECTION:shared,RWS")
复制代码
  1.     从以上的定义可以得出,所有调用ShareLib的应用程序的实例共享的数据为:iTotal和szStrings。用于存储数据的内存大小可以计算得出:iTotal需要4字节,szStrings需要64?32?2字节,一共需要约4 100字节。
  2. /SECTION:shared,RWS
复制代码
用于共享内存的动态链接库的核心代码如下:
  1. [/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]
  2. /*
  3. ----------------------------------------------
  4. // ShareLib.h
  5. ----------------------------------------------
  6. */
  7. #include <stdlib.h>
  8. #include <malloc.h>
  9. #include <windows.h>
  10. #include <wchar.h>       // for wide-character string functions
  11. #ifdef __cplusplus
  12. #define EXPORT extern "C" __declspec (dllexport)
  13. #else
  14. #define EXPORT __declspec (dllexport)
  15. #endif
  16.    
  17. #define MAX_STRINGS  64  // [font=宋体]定义在[/font]DLL[font=宋体]中最多可以存储[/font]64[font=宋体]个字符串[/font]
  18. #define MAX_LENGTH  32  // [font=宋体]定义字符串长度不能超过[/font]32?2[font=宋体]字节[/font]
  19.    
  20. // [font=宋体]预定义一个用于回调的函数[/font]GETSTRCB[font=宋体],它含[/font]PCTSTR[font=宋体]和[/font]PVOID[font=宋体]两个参数[/font]
  21. typedef BOOL (CALLBACK * GETSTRCB) (PCTSTR, PVOID) ;
  22. EXPORT BOOL CALLBACK AddString (PCWSTR) ;
  23. EXPORT BOOL CALLBACK DeleteString (PCWSTR) ;
  24. EXPORT int CALLBACK GetStrings (GETSTRCB, PVOID) ;
  25. /*
  26. ----------------------------------------------
  27. // ShareLib.c
  28. ----------------------------------------------
  29. */
  30. #include "sharelib.h"
  31.    
  32. #pragma data_seg ("shared")
  33. int   iTotal=0 ;
  34. WCHAR szStrings [MAX_STRINGS][MAX_LENGTH 1]={ '\0' };
  35. #pragma data_seg ()
  36. #pragma comment(linker,"/SECTION:shared,RWS")
  37. int WINAPI DllMain (HINSTANCE hInstance, DWORD fdwReason, PVOID pvReserved)
  38. {
  39.      return TRUE;
  40. }
  41. // [font=宋体]用于将从对话框中接收到的字符串存储到共享内存中[/font]
  42. EXPORT BOOL CALLBACK AddString (PCWSTR pStringIn)
  43. {
  44.      PWSTR pString;
  45.      int  i, iLength;
  46.      
  47.      if (iTotal == MAX_STRINGS - 1)
  48.           return FALSE;
  49.      
  50.      if ((iLength=wcslen (pStringIn)) == 0)
  51.      {
  52.          MessageBox( NULL, "Please Input Number Or Char", "No Input ",
  53. MB_OK | MB_ICONINFORMATION);
  54.        return FALSE ;
  55.      }
  56.          
  57.      // [font=宋体]将接收的字符串拷贝到定义的私有字符串中[/font]
  58.      pString=malloc (sizeof (WCHAR) * (1 iLength));
  59.      wcscpy (pString, pStringIn);
  60.      
  61.      // [font=宋体]将要添加的字符串添加到字符串数组[/font]
  62.      wcscpy (szStrings[iTotal ], pString);
  63.      
  64.      free (pString);
  65.      return TRUE;
  66. }
  67.      
复制代码
EXPORT BOOL CALLBACK DeleteString (PCWSTR pStringIn)
{
     int i, j;
     
     if (0 == wcslen (pStringIn))
     {
      MessageBox( NULL, &quot
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 ;
               
    ………………………………
}
   
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
V8 之旅:对象表示
打包时字符串多国语言问题(Checks for incomplete translations where not all strings are translated)
VS2010/MFC编程入门之十八(对话框:字体对话框)
C# 中的枚举器
JS 字符串连接性能
Go 语言入门教程(五)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服