首页 > 系统相关 >windows DLL技术-DLL使用共享内存

windows DLL技术-DLL使用共享内存

时间:2024-10-28 23:16:47浏览次数:5  
标签:NULL windows DLL process memory 共享内存 lpvMem

仅当加载 DLL 时,共享 DLL 内存才会保留。 应用程序可以使用 SetSharedMem 和 GetSharedMem 函数访问共享内存。以下示例演示 DLL 入口点函数如何使用文件映射对象来设置可由加载 DLL 的进程共享的内存。

实现共享内存的 DLL

该示例使用文件映射将命名共享内存块映射到加载 DLL 的每个进程的虚拟地址空间中。 为此,入口点函数必须:

  • 调用 CreateFileMapping 函数以获取文件映射对象的句柄。 加载 DLL 的第一个进程创建文件映射对象。 后续进程打开现有对象的句柄。 有关详细信息,请参阅 创建File-Mapping对象;
  • 调用 MapViewOfFile 函数将视图映射到虚拟地址空间。 这使进程能够访问共享内存;

请注意,虽然可以通过为 CreateFileMapping 的 lpAttributes 参数传入 NULL 值来指定默认安全属性,但可以选择使用 SECURITY_ATTRIBUTES 结构来提供额外的安全性。

// The DLL code

#include <windows.h> 
#include <memory.h> 
 
#define SHMEMSIZE 4096 
 
static LPVOID lpvMem = NULL;      // pointer to shared memory
static HANDLE hMapObject = NULL;  // handle to file mapping

// The DLL entry-point function sets up shared memory using a 
// named file-mapping object. 
 
BOOL WINAPI DllMain(HINSTANCE hinstDLL,  // DLL module handle
    DWORD fdwReason,              // reason called 
    LPVOID lpvReserved)           // reserved 
{ 
    BOOL fInit, fIgnore; 
 
    switch (fdwReason) 
    { 
        // DLL load due to process initialization or 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
                TEXT("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,     // object 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; 
 
        // DLL unload due to process termination or 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); 
} 

// The export mechanism used here is the __declspec(export)
// method supported by Microsoft Visual Studio, but any
// other export method supported by your development
// environment may be substituted.

#ifdef __cplusplus    // If used by C++ code, 
extern "C" {          // we need to export the C interface
#endif
 
// SetSharedMem sets the contents of the shared memory 
 
__declspec(dllexport) VOID __cdecl SetSharedMem(LPWSTR lpszBuf) 
{ 
    LPWSTR lpszTmp; 
    DWORD dwCount=1;
 
    // Get the address of the shared memory block
 
    lpszTmp = (LPWSTR) lpvMem; 
 
    // Copy the null-terminated string into shared memory
 
    while (*lpszBuf && dwCount<SHMEMSIZE) 
    {
        *lpszTmp++ = *lpszBuf++; 
        dwCount++;
    }
    *lpszTmp = '\0'; 
} 
 
// GetSharedMem gets the contents of the shared memory
 
__declspec(dllexport) VOID __cdecl GetSharedMem(LPWSTR lpszBuf, DWORD cchSize) 
{ 
    LPWSTR lpszTmp; 
 
    // Get the address of the shared memory block
 
    lpszTmp = (LPWSTR) lpvMem; 
 
    // Copy from shared memory into the caller's buffer
 
    while (*lpszTmp && --cchSize) 
        *lpszBuf++ = *lpszTmp++; 
    *lpszBuf = '\0'; 
}
#ifdef __cplusplus
}
#endif

共享内存可以映射到每个进程中的不同地址。 因此,每个进程都有自己的 lpvMem 实例,lpvMem 声明为全局变量,以便它可用于所有 DLL 函数。 该示例假定 DLL 全局数据不共享,因此加载 DLL 的每个进程都有自己的 lpvMem 实例。

请注意,当文件映射对象的最后一个句柄关闭时,将释放共享内存。 若要创建永久性共享内存,需要确保某些进程始终具有文件映射对象的打开句柄。

使用共享内存的进程

以下进程使用上面定义的 DLL 提供的共享内存。 第一个进程调用 SetSharedMem 来编写字符串,而第二个进程调用 GetSharedMem 来检索此字符串。

此过程使用 DLL 实现的 SetSharedMem 函数将字符串“这是一个测试字符串”写入共享内存。 它还启动一个子进程,该进程将从共享内存中读取字符串。

// Parent process

#include <windows.h>
#include <tchar.h>
#include <stdio.h>

extern "C" VOID __cdecl SetSharedMem(LPWSTR lpszBuf);

HANDLE CreateChildProcess(LPTSTR szCmdline) 
{ 
   PROCESS_INFORMATION piProcInfo; 
   STARTUPINFO siStartInfo;
   BOOL bFuncRetn = FALSE; 
 
// Set up members of the PROCESS_INFORMATION structure. 
 
   ZeroMemory( &piProcInfo, sizeof(PROCESS_INFORMATION) );
 
// Set up members of the STARTUPINFO structure. 
 
   ZeroMemory( &siStartInfo, sizeof(STARTUPINFO) );
   siStartInfo.cb = sizeof(STARTUPINFO); 
 
// Create the child process. 
    
   bFuncRetn = CreateProcess(NULL, 
      szCmdline,     // command line 
      NULL,          // process security attributes 
      NULL,          // primary thread security attributes 
      TRUE,          // handles are inherited 
      0,             // creation flags 
      NULL,          // use parent's environment 
      NULL,          // use parent's current directory 
      &siStartInfo,  // STARTUPINFO pointer 
      &piProcInfo);  // receives PROCESS_INFORMATION 
   
   if (bFuncRetn == 0) 
   {
      printf("CreateProcess failed (%)\n", GetLastError());
      return INVALID_HANDLE_VALUE;
   }
   else 
   {
      CloseHandle(piProcInfo.hThread);
      return piProcInfo.hProcess;
   }
}

int _tmain(int argc, TCHAR *argv[])
{
   HANDLE hProcess;

   if (argc == 1) 
   {
      printf("Please specify an input file");
      ExitProcess(0);
   }

   // Call the DLL function
   printf("\nProcess is writing to shared memory...\n\n");
   SetSharedMem(L"This is a test string");

   // Start the child process that will read the memory
   hProcess = CreateChildProcess(argv[1]);

   // Ensure this process is around until the child process terminates
   if (INVALID_HANDLE_VALUE != hProcess) 
   {
      WaitForSingleObject(hProcess, INFINITE);
      CloseHandle(hProcess);
   }
   return 0;
}

此过程使用 DLL 实现的 GetSharedMem 函数从共享内存中读取字符串。 它由上述父进程启动。

// Child process

#include <windows.h>
#include <tchar.h>
#include <stdio.h>

extern "C" VOID __cdecl GetSharedMem(LPWSTR lpszBuf, DWORD cchSize);

int _tmain( void )
{
    WCHAR cBuf[MAX_PATH];

    GetSharedMem(cBuf, MAX_PATH);
 
    printf("Child process read from shared memory: %S\n", cBuf);
    
    return 0;
}

标签:NULL,windows,DLL,process,memory,共享内存,lpvMem
From: https://blog.csdn.net/m0_72813396/article/details/143246074

相关文章

  • windows DLL技术-可执行文件的链接
    可执行文件通过以下两种方式之一链接到(或加载)DLL:隐式链接,其中操作系统会与使用DLL的可执行文件同时加载它。客户端可执行文件调用DLL的导出函数的方式与函数进行静态链接并包含在可执行文件中时的方式相同。隐式链接有时称为静态加载或加载时动态链接;显式链接,其中操......
  • MaskGCT,AI语音克隆大模型本地部署(Windows11),基于Python3.11,TTS,文字转语音
    前几天,又一款非自回归的文字转语音的AI模型:MaskGCT,开放了源码,和同样非自回归的F5-TTS模型一样,MaskGCT模型也是基于10万小时数据集Emilia训练而来的,精通中英日韩法德6种语言的跨语种合成。数据集Emilia是全球最大且最为多样的高质量多语种语音数据集之一。本次分享一下如何在本地......
  • 边境游戏遭遇d3dx9_43.dll缺失危机?揭秘边境游戏d3dx9_43.dll缺失的真正原因与解决方案
    当你在享受《边境》这款游戏的精彩内容时,突然弹出一个错误提示:“d3dx9_43.dll缺失”。这个提示可能会让你感到困惑和沮丧,但不必过于担心,本文将为你揭秘d3dx9_43.dll缺失的真正原因,并提供有效的解决方案。d3dx9_43.dll文件的重要性d3dx9_43.dll是DirectX9的一个关键组件,是Wi......
  • vba6.dll缺失怎么办?解决vba6.dll缺失问题详细修复步骤
    在使用MicrosoftOffice或相关应用程序时,有时可能会遇到“vba6.dll缺失”的错误提示。这个动态链接库(DLL)文件对于VisualBasicforApplications(VBA)的运行至关重要,一旦缺失或损坏,可能会导致Office应用程序无法正常工作,甚至无法启动VBA代码。本文将为你提供详细的修复步骤,帮助你......
  • gdpfile.dll文件丢失/损坏?应对gdpfile.dll缺失或损坏的全面解决方案
    gdpfile.dll文件丢失或损坏是一个常见的问题,可能会影响到相关应用程序的正常运行。以下是一套全面的解决方案,旨在帮助用户解决gdpfile.dll文件缺失或损坏的困扰:一、初步检查与重启检查错误消息:当应用程序报告gdpfile.dll文件丢失或损坏时,请仔细阅读错误消息,以获取更多关......
  • 《Dead Cide Club死神俱乐部》报错大揭秘:innocallback.dll文件丢失的解决办法
    对于热爱《DeadCideClub死神俱乐部》这款游戏的玩家来说,遇到游戏报错,特别是提示“innocallback.dll文件丢失”时,无疑是一件令人沮丧的事情。然而,不必过于担心,本文将为你揭秘这一问题的原因,并提供详细的解决办法,帮助你迅速恢复游戏的正常运行。一、了解innocallback.dll文件......
  • d3dx9_43.dll缺失导致小小世界Smalland无法启动?小小世界Smalland玩家必看d3dx9_43.dll
    当d3dx9_43.dll文件缺失导致小小世界Smalland无法启动时,作为玩家,你可以采取以下紧急应对措施来解决这一问题:一、了解d3dx9_43.dll文件的重要性d3dx9_43.dll是DirectX9.0c的一个重要组件,它负责为基于DirectX技术的游戏和应用程序提供图形和声音效果的支持。如果该文件缺失或......
  • 如何在Windows 10/11中轻松实现PDF到Word的
    PDF到Word的转换在工作场所是常见需求。编辑Word文档比PDF更加方便,因为PDF是只读文件。如果你希望在与他人共享之前对文档进行一些修改,选择Word文档会更合适。本文将介绍如何在Windows10/11中将PDF转换为Word的可行方法。请继续阅读。第1部分:有关如何在W......
  • 《聆听音乐》上传资源提示DLL文件丢失:修复步骤与技巧详解
    当您在尝试使用“聆听音乐”(或其他类似的应用程序)上传资源时遇到丢失DLL文件的问题,这通常意味着应用程序缺少了运行所必需的某些系统文件。解决这类问题的一般步骤如下:确认错误信息:首先,请仔细阅读错误提示中的具体信息,了解是哪个具体的DLL文件丢失或损坏。安装DLL修复工具:......
  • 《星速磁力》软件下载电影时DLL文件找不到?简单几步帮你解决
    当星速磁力bt下载资源时提示丢失DLL文件,可以通过以下几种方法解决:重新安装星速磁力软件:卸载现有程序:通过控制面板的“程序和功能”选项彻底卸载现有的星速磁力软件。在卸载过程中,注意勾选“删除相关配置文件”等选项,以确保卸载干净。清理残留文件:卸载完成后,手动删......