其他语言

本类阅读TOP10

·基于Solaris 开发环境的整体构思
·使用AutoMake轻松生成Makefile
·BCB数据库图像保存技术
·GNU中的Makefile
·射频芯片nRF401天线设计的分析
·iframe 的自适应高度
·BCB之Socket通信
·软件企业如何实施CMM
·入门系列--OpenGL最简单的入门
·WIN95中日志钩子(JournalRecord Hook)的使用

分类导航
VC语言Delphi
VB语言ASP
PerlJava
Script数据库
其他语言游戏开发
文件格式网站制作
软件工程.NET开发
关于在动态链接库中共享存储的简单示例,译自MSDN

作者:未知 来源:月光软件站 加入时间:2005-5-13 月光软件站

  本节将示范如何利用文件映像使得入口点函数创建可被载入该DLL的进程共享的存储。该共享的DLL存储仅存活于DLL载入期间。

  示例通过文件映像把一个命名的共享存储块映射到载入DLL的每个进程的虚地址空间中。要达到该目的,入口点函数必须:

  1.  调用 CreateFileMapping 函数获取一个文件映像对象的句柄。第一个载入DLL的进程创建文件映像对象,后续的进程仅打开存在对象的句柄。更多信息,参照“文件映像对象”。
  2. 通过调用 MapViewOfFile 函数可以把一个view映射到虚地址空间,使得进程能访问共享存储。更多信息,参照创建文件视图(File View)。

(译者注:通过查看MapViewOfFile的详细说明,MapViewOfFile把一个文件的View映射到调用进程的地址空间内;并根据以下代码,我认为View在这里翻译成视图应该是可以的,File View应该表示的是文件的一种查看方式)

// File:  DLLSHMEM.C. 
// The DLL entry-point function sets up shared memory using 
// a named file-mapping object. 

#include <windows.h> 
#include <memory.h> 
 
#define SHMEMSIZE 4096 
 
static LPVOID lpvMem = NULL; // pointer to shared memory
 
BOOL DllMain(HINSTANCE hinstDLL,  // DLL module handle
    DWORD fdwReason,              // reason called 
    LPVOID lpvReserved)           // reserved 
{ 
    HANDLE hMapObject = NULL;  // handle to file mapping
    BOOL fInit, fIgnore; 
 
    switch (fdwReason) 
    { 
        // The DLL is loading due to process 
        // initialization or a call to LoadLibrary. 
 
          case DLL_PROCESS_ATTACH: 
 
            // Create a named file mapping object.
 
            hMapObject = CreateFileMapping( 
                INVALID_HANDLE_VALUE, // use paging file
                NULL,                 // default security attributes
                PAGE_READWRITE,       // read/write access
                0,                    // size: high 32-bits
                SHMEMSIZE,            // size: low 32-bits
                "dllmemfilemap");     // name of map object
            if (hMapObject == NULL) 
                return FALSE; 
 
            // The first process to attach initializes memory.
 
            fInit = (GetLastError() != ERROR_ALREADY_EXISTS); 
 
            // Get a pointer to the file-mapped shared memory.
 
            lpvMem = MapViewOfFile( 
                hMapObject,     // to map view of
                FILE_MAP_WRITE, // read/write access
                0,              // high offset:  map from
                0,              // low offset:   beginning
                0);             // default: map entire file
            if (lpvMem == NULL) 
                return FALSE; 
 
            // Initialize memory if this is the first process.
 
            if (fInit) 
                memset(lpvMem, '\0', SHMEMSIZE); 
 
            break; 
 
        // The attached process creates a new thread. 
 
        case DLL_THREAD_ATTACH: 
            break; 
 
        // The thread of the attached process terminates.
 
        case DLL_THREAD_DETACH: 
            break; 
 
        // The DLL is unloading from a process due to 
        // process termination or a call to FreeLibrary. 
 
        case DLL_PROCESS_DETACH: 
 
            // Unmap shared memory from the process's address space.
 
            fIgnore = UnmapViewOfFile(lpvMem); 
 
            // Close the process's handle to the file-mapping object.
 
            fIgnore = CloseHandle(hMapObject); 
 
            break; 
 
        default: 
          break; 
     } 
 
    return TRUE; 
    UNREFERENCED_PARAMETER(hinstDLL); 
    UNREFERENCED_PARAMETER(lpvReserved); 
} 
 
// SetSharedMem sets the contents of shared memory. 
 
VOID SetSharedMem(LPTSTR lpszBuf) 
{ 
    LPTSTR lpszTmp; 
 
    // Get the address of the shared memory block.
 
    lpszTmp = (LPTSTR) lpvMem; 
 
    // Copy the null-terminated string into shared memory.
 
    while (*lpszBuf) 
        *lpszTmp++ = *lpszBuf++; 
    *lpszTmp = '\0'; 
} 
 
// GetSharedMem gets the contents of shared memory. 
 
VOID GetSharedMem(LPTSTR lpszBuf, DWORD cchSize) 
{ 
    LPTSTR lpszTmp; 
 
    // Get the address of the shared memory block.
 
    lpszTmp = (LPTSTR) lpvMem; 
 
    // Copy from shared memory into the caller's buffer.
 
    while (*lpszTmp && --cchSize) 
        *lpszBuf++ = *lpszTmp++; 
    *lpszBuf = '\0'; 
}

注意 共享存储能被映射到每个进程的不同地址中,所以,每个进程拥有自己的lpvMem参数实例,该参数作为全局变量声明,对DLL中所有函数都可用。该例假定DLL的全局数据不共享,所以,载入每个进程该DLL的进程都有自己的lpvMem实例。

  该例中,文件映像对象最后一个句柄关闭时,共享内存将释放,要创建永久的共享内存,DLL可以在首次载入时,通过一个分派处理创建。如果分派处理使用了DLL,而且没有终止,就会得到一个到拒绝释放共享内存的文件映射对象的句柄。




相关文章

相关软件