我正在编写一个使用外部动态库的 .NET 4.5 控制台应用程序,但我无法访问这些库的源代码。问题在于这些DLL可能会发出 segmentation fault 信号,并且当发生这种情况时,整个过程将立即终止。我当前的解决方案是将依赖于dll的代码作为单独的进程运行,然后检索结果,但是我注意到这种解决方案不是很有效。
为了说明我的问题,我制作了一个示例代码:
#include <signal.h>
__declspec(dllexport) void err(void)
{
raise(SIGSEGV);
}
using System;
using System.Runtime.InteropServices;
namespace ConsoleApp
{
class Program
{
[DllImport("segFault.dll")]
extern static void err();
static void Main(string[] args)
{
try
{
Console.Write("started");
err();
Console.WriteLine("running");
}
catch(Exception ex)
{
Console.WriteLine("Exception:" + ex.Message);
}
}
}
}
使用这种设置,我将永远不会到达“运行中”或“异常:”代码,因为在遇到segfault信号时,整个过程将终止。 我试图弄乱应用程序域,但也没有获得很大的成功。
using System;
using System.Linq;
using System.Runtime.InteropServices;
namespace ConsoleApp
{
class Program
{
[DllImport("segFault.dll")]
extern static void err();
static void Main(string[] args)
{
if (!args.Any())
{
AppDomain.CreateDomain("testdomain")
.ExecuteAssemblyByName("ConsoleApp", "1");
Console.ReadKey();
}
try
{
Console.Write("started");
err();
Console.WriteLine("running");
}
catch (Exception ex)
{
Console.WriteLine("Exception:" + ex.Message);
}
}
}
}
我还尝试过使用一个简单的包装器桥接P / Invoke执行,然后将该包装器动态加载到主可执行文件中,而且也没有成功。
// Bridge.dll
using System.Runtime.InteropServices;
namespace Bridge
{
public static class Bridge
{
[DllImport("segFault.dll")]
public static extern void err();
}
}
// Main Executable
using System;
using System.Reflection;
namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
Assembly.Load("Bridge").GetType("Bridge.Bridge")
.GetMethod("err").Invoke(null, null);
Console.WriteLine("This code will not execute");
}
}
}