You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

32位程序创建共享内存,64位进程OpenFileMapping返回错误2

问题分析与解决方案

核心原因:WOW64命名空间隔离

Windows的WOW64子系统会对32位和64位进程的命名内核对象(如文件映射)做隔离处理。默认情况下:

  • 32位进程创建的命名文件映射会被放置在WOW64专属命名空间(\Sessions\<会话ID>\BaseNamedObjects\WOW64)
  • 64位进程默认访问的是原生命名空间(\Sessions\<会话ID>\BaseNamedObjects)

这种隔离直接导致64位进程无法直接找到32位进程创建的未指定全局命名空间的共享内存对象。

为什么测试程序可以正常工作?

测试程序代码无额外上下文干扰(如UAC虚拟化、会话差异、编码宏冲突),而你的原64位程序存在隐性的环境或代码逻辑问题。


具体排查与解决步骤

1. 强制使用全局命名空间前缀修改共享内存名称

修改32位程序创建共享内存的名称,添加Global\前缀,同时64位程序打开时也使用相同前缀:

// 32位程序创建共享内存
const char* name = "Global\\ProcServSM";
HANDLE hFile = ::CreateFileMappingA(INVALID_HANDLE_VALUE,
                  NULL,
                  PAGE_READWRITE,
                  0,
                  size,
                  name);

// 64位程序打开共享内存
const char* name = "Global\\ProcServSM";
HANDLE hFile = ::OpenFileMappingA(FILE_MAP_ALL_ACCESS,
    TRUE,
    name);

注意:使用Global\前缀需要进程拥有SeCreateGlobalPrivilege权限,普通桌面进程默认具备该权限,但服务进程可能需要额外配置权限。

2. 排查编码宏冲突

确认原64位程序及依赖库中是否意外定义了_UNICODE或UNICODE宏:

  • 若代码使用TCHAR或隐式调用CreateFileMapping/OpenFileMapping(未加A后缀),当64位程序定义了UNICODE宏,会自动调用宽字符版本(CreateFileMappingW),而32位程序用的是ANSI版本(CreateFileMappingA),导致名称编码不匹配。
  • 解决方式:统一使用显式的ANSI版本函数(CreateFileMappingA、OpenFileMappingA),确保名称字符串编码完全一致。

3. 检查UAC虚拟化与权限上下文

  • 确认32位程序和64位程序是否运行在同一权限级别(如均为普通用户或均为管理员)。若权限级别不同,UAC虚拟化会隔离命名对象。
  • 临时验证:右键程序属性→兼容性→勾选「禁用UAC虚拟化」,重新运行程序测试。

4. 确认会话一致性

若32位程序是服务进程(运行在Session 0),64位程序是桌面进程(运行在Session 1及以上),默认的Local\命名空间对象无法跨会话访问,必须使用Global\前缀。

5. 验证名称变量的一致性

检查原64位程序中使用的共享内存名称是否与32位程序完全一致:

  • 排查是否在名称中拼接了进程ID、路径或其他动态值,导致实际名称不匹配。
  • 用Process Explorer工具验证:找到32位进程→右键属性→Handles→查找类型为Section的对象,查看其实际名称,与64位程序使用的名称对比。

内容的提问来源于stack exchange,提问作者user3407352

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 17:24:15