2011-07-15 105 views
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; 
} 
+0

如果我是正确的,不会P/Invoke将非托管错误“转换”为可以捕获的托管异常? –

+2

@SimpleCoder:是的,但它不会撤销野指针造成的伤害。 –

+0

它非常简单。如果你的指针不好,那么处理这个问题就没有好的办法。假设这个库本身就是一个程序,所有这些都会导致程序崩溃,这与“OutOfMemoryException”类似,在这种情况下根本无法从中恢复。 –

回答

4

如果你确定,这些问题是在库中的错误,而不是你在恶劣的参数传递的结果,那么你最可靠的方案是与加载库中的托管进程的进程间通信。这样你的操作系统进程分离使图书馆不必停止你的应用程序。

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

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

+0

访问冲突只是一个例子。一般来说,我的意思是没有被标准异常处理引起的错误。 – Novalis