【问题标题】:C++ application crashes in a 64 bit version of windows but works fine on 32 bit windowsC++ 应用程序在 64 位版本的 Windows 中崩溃,但在 32 位 Windows 上运行良好
【发布时间】:2015-08-18 07:14:55
【问题描述】:

所以我有一个 Visual C++ 应用程序,在我的代码中我使用 CoCreateInstance 函数来创建一个 COM 对象并从该对象获取一个接口:

https://msdn.microsoft.com/en-us/library/windows/desktop/ms686615(v=vs.85).aspx

这个函数:

hr = CoCreateInstance(CLSID_CppCmnBL, NULL, CLSCTX_INPROC_SERVER, 
         IID_ICppCmnBL, reinterpret_cast<void**>(&m_pBL)); 

在 32 位版本的 windows 上运行良好,但在 64 位版本的 windows 上失败。

我到处查看,似乎在 64 位系统上注册 32 位对象存在问题。

相关问题:

https://social.msdn.microsoft.com/Forums/en-US/3841717c-a736-46d0-b214-0b047efcd16c/32-bit-app-cocreateinstance-failed-on-64-bit-windows-with-error-0x80090006-invalid-signature?forum=vclanguage

http://forums.codeguru.com/showthread.php?400956-32-bit-app-CoCreateInstance-fails-on-64-bit

我得到的异常是:System.AccessViolationException

【问题讨论】:

  • 32 位程序不能加载 64 位 DLL,反之亦然,这对于 COM 意味着进程内服务器必须与主机进程的位数相匹配。如果对象支持,您可以尝试将其创建为进程外服务器。
  • @JonathanPotter 好的,让我进一步解释一下,我的应用程序是一个 32 位应用程序,现在我试图在 64 位 Windows 上运行它,它运行良好,除了应用程序中的某些功能我必须使用 CoCreateInstance 函数,但它现在失败了。
  • @JonathanPotter 我的应用程序在 64 位 Windows 环境中作为 32 位进程运行
  • 好的,你有正确注册的 32 位版本的 COM DLL 吗?
  • @JonathanPotter 我不想加载 64 位 dll

标签: c++ .net com


【解决方案1】:

请这样做:

  1. 澄清所涉及的#/二进制文件。

我假设您有一个 .exe(调用 CoCreateInstance() 的那个)和一个 .dll(您尝试实例化的 Com/ActiveX 对象)。这是正确的吗?

  1. 请在您的二进制文件上运行dumpbin /all 并发布结果。

请在所有相关的二进制文件上运行dumpbin; 尤其是 COM/ActiveX 类。

Win32 .dll 应该是这样的:

FILE HEADER VALUES
             14C machine (x86)
               3 number of sections
        5355B2AD time date stamp Mon Apr 21 17:07:09 2014
               0 file pointer to symbol table
               0 number of symbols
              E0 size of optional header
            2102 characteristics
                   Executable
                   32 bit word machine
                   DLL

OPTIONAL HEADER VALUES
             10B magic # (PE32)
  1. 请说明您尝试使用您的 MSVS 6 编译器。

MSVS 6 不适用于 .Net; MSVS 6 不会构建 C++11 代码……但如果您想要做的只是让旧版应用程序正常工作,那应该没问题。同样,我假设混合中只有一个 .exe 和一个 .dll。

我假设 .exe 可以编译为 32 位 Win32 .exe(不是 .Net .exe),而 .dll 是 Win32、COM/ActiveX 类。两者都应该在转储箱中具有“PE32”标头。否则请告知。

我假设您可以控制并且可以重新构建和调试此应用的所有相关源代码。否则请告知。

  1. 您应该能够使用 regsvr32 注册 COM/ActiveX .dll。

如果你不能,那可能是“有问题”的一个指标,我会把你的故障排除工作集中在那里。

希望对你有帮助!

【讨论】:

  • 如何运行 dumpobj /all ?
  • "dumpbin/all" 不能返回 "nothing"。在最低,它会说类似d:\temp\tmp.txt : warning LNK4048: Invalid format file; ignored。但它应该告诉你很多事情:包括它是否是 x86,是否是 32 位,以及它是否是 PE32 对象格式。问:您是否正在使用您的(非常旧的,大约 2000 年)MSVS 6 编译器重建有问题的 .dll?问:CLSCTX_INPROC_SERVER 是你想要的,不是吗?它是如何“过去工作”的?
  • PS:System.AccessViolationException 暗示 .Net .exe。您不可能使用 MSVS 6 构建 .Net exe,对吗?
  • @Eric - 请说明您的 exe 应用程序是 .NET 还是 VC++。如果它是 .NET 并且使用 Any CPU 配置构建,并且在 x64 Windows 上运行,那么它是 64 位应用程序,并且您的 VC++ 代码也需要是 64 位的。
  • @EricBergman:它是否构建在 x86 机器上并不重要,重要的是编译选项是什么。请在您的问题中添加所有相关信息。
猜你喜欢
  • 2013-04-20
  • 1970-01-01
  • 2011-03-18
  • 2012-04-17
  • 1970-01-01
  • 1970-01-01
  • 2010-12-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多