在使用托管代码时处理非托管代码中的错误(C ++,C,C ++ / CLI,C#)

6
我正在使用一个写得很糟糕的第三方(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不会将非托管错误“转换”为托管异常,以便您可以捕获它们吗? - Chris Laplante
2
@SimpleCoder:是的,但它无法撤消野指针造成的损害。 - Ben Voigt
这很简单。如果你有错误的指针,那么处理这个问题就没有真正好的方法。假设库本身是一个程序,那么所有会发生的事情就是程序崩溃,这类似于“OutOfMemoryException”,在这种情况下根本没有恢复的方法。 - Security Hound
@Ramhound 我不想恢复任何内容,只是想知道它是否发生。如果出现 "OutOfMemoryException",您可以知道它(可以记录日志),也许什么都不做。但我无法捕获(或优雅地通知)这些错误。[因此没有关于错误的记录日志] - Novalis
1个回答

4
如果您确定问题是库中的错误,而不是由于传递了错误参数引起的,则最可靠的选择是与加载库的托管进程进行进程间通信。这样,您的操作系统进程隔离会防止库导致应用程序崩溃。
您可以尝试使用SEH在进程内捕获访问冲突,但如果库写入野指针而不是简单的空指针,则即使有异常处理程序,进程也无法幸存。
您的示例不会导致访问冲突,它是堆栈上缓冲区溢出,因此相邻的内存位置包含其他有效数据,会被覆盖。

访问冲突只是一个例子。通常我指的是那些不被标准异常处理捕获的错误。 - Novalis

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