您可以处理来自非托管代码的 SIGABRT,但它有点混乱。有可能它可以完全在 C# 中完成,但我的方法需要一个 C++/CLI 程序集才能使其工作(至少它在一个过程中)。
步骤 1:创建一个 C++/CLI 类库项目,在 *.h 文件中放入以下函数
namespace ClassLibrary1 {
public ref class Class1
{
public:
static void callaborter();
};
}
第2步:在cpp文件中输入以下代码:
// This is the main DLL file.
#include "stdafx.h"
#include <csetjmp>
#include <csignal>
#include <cstdlib>
#include <iostream>
#include "ClassLibrary1.h"
#include "..\Win32Project1\Win32Project1.h"
#pragma managed(push, off)
jmp_buf env;
void on_sigabrt (int signum)
{
longjmp (env, 1);
}
void run()
{
if (setjmp (env) == 0) {
signal(SIGABRT, &on_sigabrt);
fnWin32Project1();
}
else {
std::cout << "aborted\n";
}
}
#pragma managed(pop)
void ClassLibrary1::Class1::callaborter()
{
run();
}
我将我的类库和类的名称保留为默认值,我的中止函数是调用 fnWinProject1()。您需要将有问题的 DLL 直接链接到该项目(就像在 C++ 中一样)
在您的 C# 类中,包含对 C++/CLI 程序集的引用并调用“callaborter”方法。
运行中的代码将为 SIGABRT 设置一个捕获器(由 abort() 调用)并在 on_sigabrt() 中对其进行处理,这将导致整个函数退出。然后,您可以清理并重试。
我将把它作为 OP 选择有用名称的练习。
注意:在 Debug 中,您仍然会看到 abort 对话框,只需按 Ignore 继续。在 Release 中,您将看不到该对话框。
PS我应该提到我基于这个stackoverflow问题建立了我的回复:如何处理SIGABRT信号?