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

C# 在托管代码(C+;+;,C,C+;+;/CLI,C)中使用非托管代码时处理错误,c#,c++,exception,exception-handling,C#,C++,Exception,Exception Handling,我使用的是一个写得很糟糕的第三方(C/C++)Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这会使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,我该怎么办] 但我不希望我的应用程序整体崩溃。至少,如果真的有问题,我的应用程序应该优雅地说“好的。我不能做我的工作。再见。”:-)然后它至少执行一些替代场景,最后关闭自己 但是似乎没有办法抓住(可能是错误的术语,可能是要被告知的)访问违规和类似的错误。有没有办法被告知这些错误。所以我可以执行我的替

我使用的是一个写得很糟糕的第三方(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;
}
#包括“stdafx.h”
#包括
使用名称空间系统;
使用名称空间std;
静态void ThrowingManagedException()
{
抛出新的ArgumentException(“无正当理由”);
}
静态void ThrowingNativeException()
{
抛出std::异常(“没有好的理由”);
}
静态void somebaddhingShappen()
{
短a[1];
a[0]=1;
a[2]=2;//有人犯了愚蠢的错误
}
int main(数组^args)
{
控制台::写线(L“测试异常”);
尝试
{
某物形状笔();
//ThrowingNativeException();
//ThrowingManagedException();
}
捕获(异常^e)
{
控制台::WriteLine(“发生了可怕的事情:”+e);
}
控制台::WriteLine(“按enter键退出”);
控制台::Read();
返回0;
}

如果您确定问题是库中的bug,而不是由于您传入了错误的参数,那么最可靠的选择是与加载库的宿主进程进行进程间通信。这样,操作系统进程分离可以防止库关闭应用程序

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


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

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