【问题标题】:Handling errors while using unmanaged code in a managed one ( C++, C, C++/CLI, C#)在托管代码(C++、C、C++/CLI、C#)中使用非托管代码时处理错误
【发布时间】:2011-10-06 08:15:06
【问题描述】:

我正在使用写得很糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这会导致整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等我该怎么办]。

但我不希望我的应用程序整体崩溃。至少如果有一个真正的问题,我的应用程序应该优雅地说“好的。我不能做我的工作。再见。” :-) 然后它至少执行一些替代方案并最终关闭自己。

但是似乎没有办法捕获(可能是错误的术语,正确的词可能是被告知)访问冲突和类似的错误。有没有办法被告知这些错误。所以我可以执行我的替代方案。

PS:标准异常处理不能解决这个问题。

#include "stdafx.h"
#include <iostream>

using namespace System;

using namespace std;


static void ThrowingManagedException()
{

    throw gcnew ArgumentException("For no good reason");

}

static void ThrowingNativeException()
{

    throw std::exception("For no good reason");



}

static void SomeBadThingsHappen()
{

    short a[1]; 

    a[0]=1;

    a[2]= 2; // SomeOne make stupid mistake

}

int main(array<System::String ^> ^args)
{
    Console::WriteLine(L"Test Exceptions");

    try 
    {

        SomeBadThingsHappen();
         //ThrowingNativeException();         
         //ThrowingManagedException();
    }


    catch(Exception^ e)
    {
        Console::WriteLine("Something awful happened: "+ e);
    }


    Console::WriteLine("Press enter to exit");
    Console::Read();

    return 0;
}

【问题讨论】:

  • 如果我是正确的,P/Invoke 不会将非托管错误“转换”为您可以捕获的托管异常吗?
  • @SimpleCoder:是的,但它不会撤消野指针造成的损害。
  • 真的很简单。如果您有错误的指针,则没有真正好的方法来处理该问题。假设库本身就是一个程序,那么会发生的只是程序崩溃,这类似于“OutOfMemoryException”,根本无法从中恢复。
  • @Ramhound 我不想恢复任何东西。我只是想知道它。如果发生“OutOfMemoryException”,您可以知道它(可以记录它)并且可能什么也不做。但我不能(或被优雅地告知)这些错误。[所以没有记录错误]

标签: c# c++ exception exception-handling


【解决方案1】:

如果您确定问题是库中的错误,而不是您传递错误参数的结果,那么您最可靠的选择是与加载库的托管进程进行进程间通信。这样一来,您的操作系统进程分离就可以防止库导致您的应用程序崩溃。

您可以尝试使用 SEH 在进程中捕获访问冲突,但如果库写入野指针而不是简单的空指针,那么即使使用异常处理程序,该进程也将无法生存。

您的示例不会导致访问冲突,它是堆栈上缓冲区的缓冲区溢出,因此相邻的内存位置包含其他一些被踩踏的有效数据。

【讨论】:

  • 访问违规只是一个例子。通常我的意思是标准异常处理无法解决的错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-29
  • 1970-01-01
相关资源
最近更新 更多