【问题标题】:Handling exceptions thrown from a .NET dll in C++/MFC app在 C++/MFC 应用程序中处理从 .NET dll 引发的异常
【发布时间】:2011-05-26 11:33:48
【问题描述】:

我正在使用通过 COM 与 C#.NET 组件交互的 C++ 应用程序。 由于 .NET dll 引发的一些异常,我的 C++ 应用程序正在崩溃,尽管所有异常处理机制都已到位。 是否可以在 C++ 代码中捕获 .NET dll 引发的异常?怎么样?

【问题讨论】:

  • 发生了其他事情,CLR 不会让托管异常从 COM 互操作调用中逃脱。它们总是被翻译成 HRESULT。这可能不是托管异常。
  • 我的疑问是,这一切都在同一个进程中运行,如果 .NET 代码中发生了一些致命异常(如无效的内存引用),CLR 仍然能够防止进程崩溃吗?

标签: c# .net c++ com


【解决方案1】:

我不是 COM/.NET 互操作性方面的专家,但我希望 .NET 运行时永远不会让异常通过 COM 方法调用泄漏。相反,我猜运行时会将异常转换为实现IErrorInfo 接口的对象。

[编辑] 我刚刚证实了我的假设。下面的代码打印出我怀疑的“A dot net exception...”。

// SERVER: C#
using System.Runtime.InteropServices;

namespace COMInteroperability
{
    [Guid("6650E916-B507-483e-9804-8EEDA770F76C")]
    interface IFoo
    {
        [ComVisible(true)]
        string Bar(int value);
    }

    [ClassInterface(ClassInterfaceType.AutoDual)]
    [Guid("92377D62-32CB-4b2b-AE79-B256F54B3E17")]
    public class Foo : IFoo
    {
        public string Bar(int value)
        {
            throw new Exception("A dotnet exception...");
        }
    }
}


// CLIENT: C++
#include "stdafx.h"
#import "G:\temp\COMInteroperability\COMInteroperability\COMInteroperability\bin\Debug\COMInteroperability.tlb" no_namespace names_guids raw_interfaces_only

void CheckResult(HRESULT hr)
{
    if (SUCCEEDED(hr)) return;

    CComPtr<IErrorInfo> error;
    if (FAILED(GetErrorInfo(0, &error))) return;

    if (!error.p) return;

    CComBSTR description;
    error->GetDescription(&description);
    wprintf(description.m_str);
}

int _tmain(int argc, _TCHAR* argv[])
{
    CoInitialize(0);
    {
        CComPtr<_Foo> foo;

        CLSID clsid;
        CLSIDFromString(L"{92377D62-32CB-4b2b-AE79-B256F54B3E17}", &clsid);

        HRESULT hr = foo.CoCreateInstance(clsid);

        CheckResult(hr);
        if (FAILED(hr))
        {
            printf("Error %x", hr);
            return -1;
        }

        CComBSTR ret;
        CheckResult(foo->raw_Bar(10, &ret));
    }
    CoUninitialize();
}

[/edited]

将调试器附加到您的进程并查看应用程序崩溃时的状态。

最好的

阿德里亚诺

【讨论】:

  • 所以你的意思是说我的应用程序不应该因为 .NET 组件抛出的异常而崩溃?顺便说一句,我正在检查每个呼叫的 HRESULT。
  • AFAIK,是的。正如我所说,我不是 COM/.NET 互操作性方面的专家。我相信您永远不应该允许“本机”异常从 COM 组件中泄漏。例如,永远不允许 C++ 异常从组件中泄漏,因为该组件可能在 VB 中使用(它不知道 C++ 异常是什么)。但正如我所说,我希望 .NET 运行时能够自动处理这个问题(将 .NET 异常映射到 ErrorInfo 对象)。您可以对其进行测试:只需将所有 C# 方法代码包装在 try/catch 中并记录异常(如果发生任何情况)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-08
  • 1970-01-01
  • 2010-10-17
  • 1970-01-01
  • 1970-01-01
  • 2014-06-06
相关资源
最近更新 更多