本地C DLL调用C++/CLI混合模式DLL - 未处理的异常

3
我有一个本地的C Dll,由一个老旧应用程序动态加载。这个dll的目的是基于某些应用程序事件允许覆盖应用程序行为。我有一个包含函数的C# dll,通过混合模式的C++/CLI dll从本地C dll中调用这些函数来增强这些应用程序事件。使用此架构的应用程序在Windows 2000上完美运行。
该应用程序也可以在Windows XP上运行,但不幸的是,在本地C dll在应用程序启动时被加载后,应用程序会崩溃(未处理的异常)。看起来当它尝试加载混合模式dll时会崩溃。我已经从本地C dll中删除了所有对混合模式dll的依赖项,并且应用程序可以正常启动。但是一旦添加了依赖项,就会发生崩溃。Windows 2000上的代码与在Windows XP上使用的代码相同。我无法访问应用程序代码,但可以访问本地C dll代码,但无法使调试器停止,因为崩溃发生在初始化完成之前。我怀疑这与CLR初始化和OS加载程序之间的差异有关,但不确定。我正在寻找解决此问题的建议。我正在使用VS2005使用2.0框架。非常感谢您能给出的任何帮助。
异常和堆栈跟踪并不真正有用:未处理的异常位于0x775125f6处,MyApplication.exe中读取位置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()   

...


我对这个问题感到困惑,一直在思考。我编写了一个小的测试工具来动态加载本地C dll并调用类似于应用程序代码执行的入口点。我成功地做到了这一点。有什么想法吗? - user204534
1
尝试了许多方法后,我想出了一个解决方案...我想发布我的解决方案。本地C dll以前是静态链接到托管的C++/CLI dll中的,这会导致访问冲突。不确定它是否是一种加载器锁问题或CRT初始化问题?无论如何,我删除了静态链接,现在动态加载托管的C++/CLI dll并调用入口函数,然后调用我的.NET程序集。像宝石一样工作。我仍然希望能够得到任何关于如何使用静态链接使其工作的想法。 - user204534
2个回答

2

我曾经遇到过完全相同的问题。在这个问题上,我提供了一些额外的信息和解决方案。但是我很乐意在这里总结并提供一个答案。

你所遇到的基本问题是,在将本地应用程序链接到混合模式dll和非托管dll时,链接器在执行其工作时似乎存在错误或某种可变性。似乎只有当你同时连接混合模式dll和非托管dll时,才会出现这种情况。

  • 选项1:将混合模式dll设置为延迟加载。
  • 选项2:通过在其中至少包含一个CLR感知文件,使非托管exe成为混合模式可执行文件。该文件可以为空,它只需存在以允许在可执行文件中正确链接事物。
  • 选项3:更新非托管可执行文件,以便在链接任何非托管库之前链接混合模式库。

我最终使用选项3来解决此问题,因为它似乎是最安全的。只需进入项目属性对话框,选择链接器->输入选项卡。在附加依赖项字段中指定混合模式dll的lib文件。确保混合模式库是该字段中列出的第一个库。

设置附加依赖项字段如下: mixedmode.lib;unmanaged.lib;unmanaged2.lib。

这似乎解决了非托管应用程序崩溃的问题。如果重新排列库的顺序,使非托管库首先出现,那么你将重新回到崩溃状态。

希望这有所帮助!


1

我觉得符号设置不正确。您可能需要先执行以下操作:

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

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接