C ++:带内存映射文件的DLL

时间:2013-09-25 14:48:03

标签: c++ windows memory-mapped-files

我有一个DLL,可能同时被多个应用程序调用。 此DLL内存映射文件。

我有两个问题:

1)每个应用程序都会创建自己的DLL实例,对吧? 因此,文件将多次进行内存映射

2)如果这是真的,我不明白这里发生了什么:

a)应用程序A调用DLL。 b)应用程序B调用DLL。 c)我退出应用程序A,DLL将取消映射文件。 d)应用程序B调用DLL,内存映射文件不再可用,并且调用失败。

我不明白这一点。 有人这样做吗?

谢谢。

1 个答案:

答案 0 :(得分:3)

这是因为您对1)的假设是错误的。根据定义,dll是共享的;两个应用程序都使用相同的dll实例,因此当您在一个应用程序中释放该文件时,其他应用程序将无法使用该文件。

要解决您的问题,您应该实现一些引用计数机制,以便仅在没有进程使用它时取消映射文件。

修改:@sumeet是对的。每个进程都有自己的地址空间;当两个进程加载相同的dll时,它们可能共享其只读数据以提高效率,但是它们的可写数据对于每个进程都是本地的。然而,内存映射文件是一个内核对象,如信号量,管道和共享内存。因此,如果您在一个过程中取消映射,则为所有人取消映射。

Edit2 :来自MSDN(备注部分):

  

多个进程可以通过使用a共享同一文件的视图   单个共享文件映射对象或创建单独的文件映射   由同一文件支持的对象。单个文件映射对象可以   通过在进程中继承句柄来共享多个进程   创建,复制句柄或打开文件映射对象   按名字。有关更多信息,请参阅CreateProcess,DuplicateHandle   和OpenFileMapping函数。

     

[...]

     

文件映射对象的映射视图维护内部引用   对象和文件映射对象直到全部关闭   对它的引用已经发布。因此,要完全关闭文件   映射对象,应用程序必须取消映射文件的所有映射视图   通过调用UnmapViewOfFile映射对象并关闭文件映射   通过调用CloseHandle来处理对象句柄。可以调用这些函数   任何订单。

首先,从第一段开始,每个应用程序如何初始化视图? 从第二段开始,我收集到每个应用程序调用{​​{1}}和UnmapViewofFile将释放对内存文件的所有引用,然后Windows将自动释放相关资源(即他保留引用计数,你不需要这样做)。 发布两个应用程序的内存映射初始化和关闭代码。