2013-09-25 37 views
1

我有一个DLL可能会被多个应用程序同时调用。 此DLL内存 - 映射文件。C++:带内存映射文件的DLL

我有2个问题:

1)每个应用程序会创建自己的DLL的实例,对不对? 就这样,该文件将内存映射多次

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

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

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

谢谢。

回答

3

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

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

编辑:@sumeet是正确的。每个进程都有自己的地址空间;当两个进程加载相同的dll时,他们可能会共享其只读数据以提高效率,但其可写数据对每个进程都是本地的。尽管如此,内存映射文件是一个内核对象,如信号量,管道和共享内存。因此,如果你在一个进程中取消映射,你可以全部取消映射。

EDIT2:从MSDN(备注部分):

多个进程可以通过使用 单个共享文件映射对象或创建单独的文件映射由备份 对象共享同一文件的视图同一个文件。通过继承进程 创建,复制句柄或打开文件映射对象 的名称,单个文件映射对象可以是由多个进程共享的 。有关更多信息,请参见CreateProcess,DuplicateHandle 和OpenFileMapping函数。

[...]

映射文件映射对象的视图保持内部的引用 的对象,直到所有 对它的引用被释放文件映射对象不会关闭。因此,要完全关闭映射对象文件 ,应用程序必须通过调用UnmapViewOfFile来取消映射文件 映射对象的所有映射视图,并通过调用CloseHandle来关闭文件映射 对象句柄。这些功能可以以任何顺序在 中调用。

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

+0

我没有downvote它。不知道为什么这是downvoted。你能告诉我一个参考柜台的样品吗? – tmighty

+0

我不认为你的答案是正确的。使用该Dll的每个进程都将拥有自己的全局变量和静态变量副本。 – sumeet

+0

@sumeet:你说得对。我在编辑中澄清了这一点。 –