【问题标题】:Invalid handle exception on CloseHandle call?CloseHandle 调用上的无效句柄异常?
【发布时间】:2012-06-05 18:23:40
【问题描述】:

在我的应用程序中,我打开了一个共享内存的句柄,我可以从中读取/写入。我这样打开手柄:

//Map the shared memory
     d_to_mbx_mem_arr[idx] = reinterpret_cast<Byte*>(MapViewOfFile(to_mem_h,    // handle to map object
                                                       FILE_MAP_ALL_ACCESS, // read/write permission
                                                       0,
                                                       0,
                                                       MAILBOX_SIZE_e));

这里设置的变量是一个 Byte* 数组(Byte 是 unsigned char 的别名),所以我进行了重新解释转换,所以我可以像使用标准 Byte 指针一样使用句柄。

稍后我尝试通过以下方式释放手柄:

CloseHandle(d_to_mbx_mem_arr[p_tool_id]);
d_to_mbx_mem_arr[p_tool_id] = NULL;

由于在 CloseHandle 之后值被设置为 NULL 并且调用此方法的代码只是单线程的,我知道我只调用了一次。但是,当我调用它时,会收到以下警告:

“FMLib_Comm_Layer.exe 中 0x7c90e4ff (ntdll.dll) 处的第一次机会异常:0xC0000008:指定了无效句柄。”

当我因警告而中断时,我看到它试图关闭的句柄的值为“0x01c90000”,这对我来说对于共享内存指针来说似乎是合理的。有没有人看到这个实现有问题,或者我应该假设我在其他地方搞砸了?

【问题讨论】:

  • 两个问题:(1)那个句柄值和你第一次获取句柄时得到的值是一样的吗? (2) 你打电话给UnmapViewOfFile 电话成功了吗? [你调用UnmapViewOfFileCloseHandle的顺序无关紧要,但你必须调用他们两个来释放文件。不过,两者都应该成功。]

标签: c++ windows shared-memory handles


【解决方案1】:

您需要在to_mem_h 上调用CloseHandle(),而不是在MapViewOfFile() 的返回值上(参见使用MapViewOfFile() here 的示例——该示例是在返回值上调用UnmapViewOfFile() MapViewOfFile() 并在第一个参数上调用 CloseHandle() MapViewOfFile())

【讨论】:

  • 好的,1 个问题。我实际上在映射文件视图后立即在 to_mem_h 上调用 CloseHandle,即使我继续使用已映射的共享文件,这样可以吗?
  • 其实这样也行。来自UnmapViewOfFile 文档:“尽管应用程序可能会关闭用于创建文件映射对象的文件句柄,但系统会保持相应文件处于打开状态,直到文件的最后一个视图被取消映射。”
  • 添加 UnmapViewOfFile 而不是 CloseHandle 似乎可以解决它。如果在仍然使用文件映射对象的同时关闭文件句柄是不行的,我会感到惊讶,因为我已经这样做了一段时间,没有明显的问题。
猜你喜欢
  • 2011-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-19
  • 1970-01-01
  • 2013-12-13
  • 1970-01-01
相关资源
最近更新 更多