【问题标题】:Native C Dll calling C++/CLI Mixed Mode Dll - Unhandled Exception本机 C Dll 调用 C++/CLI 混合模式 Dll - 未处理的异常
【发布时间】:2010-12-13 17:37:00
【问题描述】:

我有一个由旧应用程序动态加载的 Native C Dll。此 dll 的目的是允许基于某些应用程序事件覆盖应用程序行为。我有一个 C# dll,其中包含我通过混合模式 C++/CLI dll 从本机 C dll 调用的函数,以增强这些应用程序事件。使用这种架构的应用程序可以在 Windows 2000 上完美运行。

该应用程序也可以在 Windows XP 上运行,但不幸的是,一旦在应用程序启动时加载了 Native C dll,应用程序就会崩溃(未处理的异常)。它似乎在尝试加载混合模式 dll 时崩溃。我已经从 Native C dll 中删除了对混合模式 dll 的所有依赖项,并且应用程序可以正常启动。但是一旦添加了依赖项,就会发生崩溃。 Windows 2000 上的代码与 Windows XP 上使用的代码相同。我无权访问应用程序代码,但可以访问本机 C dll 代码,但无法让调试器停止,因为在初始化完成之前发生崩溃。我怀疑这与 CLR 初始化和操作系统加载程序差异有关,但不确定。我正在寻找有关如何解决此问题的建议。我正在使用 VS2005 使用 2.0 框架。感谢您提供的任何帮助。

异常和堆栈跟踪并没有真正的帮助:

MyApplication.exe 中 0x775125f6 处的未处理异常:0xC0000005:访问冲突读取位置 0x775125f6。

775125f6()  
user32.dll!7e418734()   
[Frames below may be incorrect and/or missing, no symbols loaded for user32.dll]    
user32.dll!7e418816()   
user32.dll!7e428ea0()   
user32.dll!7e42ce7c()   
ntdll.dll!7c90e473()    
user32.dll!7e42e389()   

...

【问题讨论】:

  • ...继续在这个问题上摸不着头脑...我编写了一个小测试工具来动态加载 Native C dll 并调用类似于应用程序代码执行的入口点。我成功地做到了这一点。对此有点困惑。有什么想法吗?
  • 在尝试了许多项目后想出了一个解决方案......我想我会发布我的解决方案。本机 C dll 以前静态链接到托管 C++/CLI dll - 这将导致访问冲突。不确定这是否是 loaderlock 问题的一种形式 - 还是 CRT 初始化?无论如何,我删除了静态链接,现在动态加载托管 C++/CLI dll 并调用入口函数,然后调用我的 .NET 程序集。像宝石一样工作。我仍然会很感激任何关于如何让它与静态链接一起工作的想法。

标签: c# c c++-cli mixed-mode


【解决方案1】:

我遇到了这个确切的问题。我在这个question 上提供了一些额外的信息和解决方法。但我也很乐意在这里总结并提供答案。

您遇到的基本问题是,在将本机应用程序链接到混合模式 dll 和非托管 dll 时,链接器的工作方式似乎存在错误或某些可变性。似乎只有在混合模式 dll 和非托管 dll 都由非托管可执行文件链接时才会发生这种情况。

  • 选项 1:将混合模式 dll 设置为延迟加载。
  • 选项 2:使非托管 exe 成为混合模式可执行文件,方法是在其中至少有一个文件可识别 CLR。该文件可以是空的,它只需要存在以允许在可执行文件中正确链接。
  • 选项 3:更新非托管可执行文件,使其在链接任何非托管库之前链接混合模式库。

我最终使用了选项 3 来解决这个问题,因为它似乎是最安全的。只需转到 Project Properties 对话框,选择 Linker->Input 选项卡。在 Additional Dependencies 字段中指定混合模式 dll 的 lib 文件。确保混合模式库是该字段中列出的第一个库。

设置 Additional Dependencies 字段如下: 混合模式.lib;unmanaged.lib;unmanaged2.lib.

这似乎解决了非托管应用程序崩溃的问题。如果你重新排列 lib 的顺序,那么 unmanaged.lib 是第一个,你最终会回到崩溃。

我希望这会有所帮助!

【讨论】:

    【解决方案2】:

    在我看来,符号设置不正确。您可能需要先执行以下操作:

    1. 为 Windows 安装调试工具 http://www.microsoft.com/whdc/devtools/debugging/default.mspx
    2. 打开命令提示符,切换到文件夹,运行WinDBG -I
    3. 运行你的程序,让它崩溃,WinDBG会被触发
    4. 输入 .symfix
    5. 输入 .sympath+
    6. type .loadby sos clr
    7. 输入 !CLRStack -a
    8. 键入 kb

    第 7 步和第 8 步应该为您提供更有意义的堆栈进行调试

    【讨论】:

      猜你喜欢
      • 2011-12-29
      • 2011-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-02
      • 2010-11-07
      • 2014-04-07
      • 2020-04-07
      相关资源
      最近更新 更多