0xC0020001: 字符串绑定无效 - 仅在WPF中出现。

23

首先,我应该说明一下我的水平可能只有五年级的程度……我在一个WPF应用程序中使用了一个C++插件。每当我尝试退出程序时,我都会收到以下错误:

Unhandled exception at 0x770d15de in Raptor.exe: 0xC0020001: The string binding is invalid.

我一直在使用这篇 博客文章 来尝试找出问题所在,但是一直没有成功。不过有一件事情我注意到了,当我在控制台应用程序中使用相同的C++插件,并调用与WPF应用程序中使用的许多相同方法时,控制台可以正常退出。

我还仔细查看了C++代码,但没有找到任何声明静态变量的地方。不过有静态方法。

非常感谢您的任何帮助!

编辑:我启用了多个调试功能以查看程序停止的位置。它在以下内容的最后一括号处断开连接(Boost的sp_counted_impl.hpp 文件):

    virtual void dispose() // nothrow
    {
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
        boost::sp_scalar_destructor_hook( px_, sizeof(X), this );
#endif
        boost::checked_delete( px_ );
    }

C++代码是完全本地的(例如通过COM或P/Invoke公开),还是带有托管扩展的C++(即VS2003),还是C++/CLI(VS2005及更高版本)? C#代码如何加载C++插件?听起来您拥有所有C++源代码并且可以进行任何必要的修改(您不是使用第三方组件);这是正确的吗? - Bradley Grainger
正确,但代码99%是由第三方编写的。我只是按了一些按钮...它在VS2008中。我使用了一些\clr东西进行编译,它链接了一堆代码(不知道那是做什么的),并且我将其设置为多线程DLL。一旦编译完成,它就会导出一个DLL,然后我将其作为引用添加到我的C#项目中。 - keynesiancross
好的,听起来像是我遇到过的同样问题(并且写了博客);如果我没记错的话,我只能通过在C++方法中使用static变量(而不是使用全局变量)来复现它,所以如果你没有找到任何static变量,我不确定是什么原因导致的。您可能需要启用非托管代码调试(项目属性,调试选项卡),在Debug > Exceptions中启用Break when Thrown,并查看在crtdll.c中调试异常是否提供任何线索... - Bradley Grainger
谢谢你的帮助 - 我会试一下这些方法。说实话,我不知道DllMain在哪里,除非它被隐藏在后台某个地方...哈,刚才才意识到我引用了你的博客。感谢你把它放在那里。我注意到你说的一件事是:即使NativeMethod被作为本机代码发出,反汇编显示它使用atexit函数为NativeClass析构函数(对于staticNativeObject)注册了一个托管入口点。有没有办法我可以这样做来尝试找到atexit的位置,以便确定可能导致问题的代码? - keynesiancross
1
要查找 atexit,您可以启用非托管代码调试,并在 _onexit_nolock(VS2008 中的 C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\crt\src\onexit.c)中设置断点。或者,在 crtdll.c 的第 444 行设置断点(同一文件夹),并添加一个观察 function_to_call。继续调试会话,直到它抛出异常。最后一个 function_to_call 可能是罪魁祸首;希望它的名称能提供在 C++ 代码中搜索的线索。 - Bradley Grainger
显示剩余3条评论
1个回答

27
这种情况发生在某些没有与本地库链接的DLL中,因此它们的DllMain没有初始化一些所需的本地子系统(如CRT或ATL)。听起来像是某种混合模式DLL。建议的解决方案之一是从托管DLL中删除入口点: 移除托管DLL的入口点
  1. 使用 /NOENTRY 进行链接。在“解决方案资源管理器”中,右键单击项目节点,单击“属性”选项。在“属性页”对话框中,单击“链接器”,单击“命令行”,然后将此开关添加到“附加选项”字段。
  2. 链接 msvcrt.lib。在“属性页”对话框中,单击“链接器”,单击“输入”,然后将msvcrt.lib添加到“附加依赖项”属性中。
  3. 移除 nochkclr.obj。在“输入”页上(与上一步相同的页),从“附加依赖项”属性中移除 nochkclr.obj。
  4. 链接 CRT。在“输入”页上(与上一步相同的页),将 __DllMainCRTStartup@12 添加到“强制符号引用”属性中。
更多细节可在此处找到:https://support.microsoft.com/en-us/kb/814472

非常感谢 - 我现在正在尝试。我注意到nochkclr.obj已经不存在了... - keynesiancross
Microsoft 支持链接不可用 :(。请更新它! - Doc
1
遗憾的是,出现了LNK2001:未解析的外部符号__DllMainCRTStartup@12 - Patrizio Bertoni
@PatrizioBertoni:我遇到了同样的问题,并找到了这个链接。它基本上说:在64位编译中,导出函数没有修饰。使用_DllMainCRTStartup(一个下划线,没有“@12”后缀)。 - Quirysse
你知道如何使用cmake进行命令行更改吗? - anand_v.singh
非常感谢。我对编程还比较新,今天不仅解决了我的问题,还学到了一个重要的概念。 - FranciscoNabas

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