【问题标题】:Exception Handling in /clr MFC Application (compiled with /EHa)/clr MFC 应用程序中的异常处理(使用 /EHa 编译)
【发布时间】:2017-08-09 01:36:01
【问题描述】:

我们有一个正在更新的大型 MFC 应用程序。它已被修改以添加一些 .NET 组件(一些 DLL 现在具有托管和本机类),其想法是旧代码将被逐步淘汰最终

该应用有许多带有本机 C++ 类的 DLL,这些 DLL 被导出并供应用使用。

在尝试测试应用时,我们现在发现 ANY 异常似乎会导致应用崩溃,即使这些异常理论上是在同一个函数中捕获的。

示例:

CString AddressClass::GetPostalAddress()
{
    CString address;
    try {
        address = (LPCSTR)(_bstr_t)m_pCommand->GetParameters()->Item["PostalAddress"]->Value;
    }
    catch ( _com_error& )//exception occurs if postal address is NULL
    {
        address = _T("");
    }
    return address;
}

使用 /clr 和 /EHa (Vs2015 更新 3) 编译时未捕获 _com_error。没有 /clr 它可以正常工作并且已经运行了多年。从我阅读的文档中我的理解是这应该有效,但显然我错了。

负责产生错误的代码在comutil.h中:

inline void CheckError(HRESULT hr)
{
    if (FAILED(hr)) {
        _com_issue_error(hr);
    }
}

来自调试器的信息是:

在 XXX.dll 中发生了“System.Runtime.InteropServices.SEHException”类型的异常,并且在托管/本机边界之前未处理

附加信息:外部组件已抛出异常。

有没有办法在不重写大量代码的情况下完成这项工作?

谢谢。

【问题讨论】:

  • 一般来说:您应该 编译这些与/clr。将旧代码与使用 CLR 的新代码分开,只需使用 /clr 编译新代码,直接本地编译旧代码/文件。您仍然可以在启用 clr 的 DLL 中将所有内容链接在一起。
  • 感谢您的反馈,我相信您是正确的。这是我应该知道的吗?我花了很多时间寻找这个解决方案
  • 应该知道吗?我敢说不是。这是我个人在几次迭代后才“得到”的东西。就个人而言,我仅将 /clr 用于胶水代码,但您的情况似乎稍微复杂一些。

标签: c++ visual-studio exception-handling command-line-interface


【解决方案1】:

从简短的评论中回答,因为它似乎有帮助:

一般来说:您应该 编译这些与/clr。将旧代码与使用 CLR 的新代码分开,只需使用 /clr 编译新代码,直接本地编译旧代码/文件。您仍然可以在启用 clr 的 DLL 中将所有内容链接在一起。

我们所做的是在单独的静态 LIB 项目中编译所有本机内容,然后将它们链接到启用 /clr 的项目中 - 在一个项目中为各个源文件设置单独的编译器开关总是有点令人困惑。但是,它可能仍然是适合您的方式。取决于混合和调用模式,我猜。

我要补充一点,我主要将 /clr 视为一个相当强大的粘合系统,而不是您应该针对完整应用堆栈的东西。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-01
    相关资源
    最近更新 更多