从非托管 C++ 代码调用 C# 函数时无法处理异常
Can't handle exceptions when invoking C# function from unmanaged C++ code
问题的思路如下:我将 C# 函数指针传递给 C++ 编译库,然后从 C++ 调用传递的函数。我想从代码中捕获 C#/C++ 异常,代码位于 before C++ 函数调用。
问题的思路如下:我将 C# 函数指针传递给 C++ 编译库,然后从 C++ 调用传递的函数。我的 C++ 调用包含在 try/catch
中,我想从 C++/C# 函数中捕获异常。
所以,我有 .NET 5 应用程序,它运行以下代码:
class NetProgram
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void CustomCppFunc(int id);
[DllImport("/root/projects/LinuxLoop/bin/x64/Debug/libLinuxLoop.so")]
protected static extern void strg_Create(IntPtr cb_is_my);
static void Main(string[] args)
{
CustomCppFunc sharpDelegate = new CustomCppFunc(Smth.sharpStaticMethod);
try
{
strg_Create(Marshal.GetFunctionPointerForDelegate(sharpDelegate));
}
catch (Exception e)
{
Console.WriteLine("Catched exception from C# Program: " + e.Message);
}
finally
{
Console.WriteLine("Finally from C# Program.");
}
}
public class Smth
{
public static void sharpStaticMethod(IntPtr id)
{
Console.WriteLine("C#. sharpStaticMethod. Invoked.");
Console.WriteLine("C#. sharpStaticMethod. Zero division.");
var b = 0;
var a = 1 / b;
}
}
}
libLinuxLoop.so 是 Linux 的 C++ 编译库(我使用的是 CentOS 7),它有以下内容:
MyCppFunc.h:
#ifdef MYCPPFUNC
#define MYCPPFUNC __attribute__((dllexport))
#else
#define MYCPPFUNC __attribute__((dllimport))
#endif
typedef void(*CBIsMy)(int order_id);
extern "C" MYCPPFUNC void *strg_Create(CBIsMy cb_is_my);
MyCppFunc.cpp:
#include <cstdio>
#include <utility>
#include <limits.h>
#include "MyCppFunc.h"
void *strg_Create(CBIsMy cb_is_my) {
std::fputs("C++. strg_Create. Invoked.\n", stdout);
std::fputs("C++. strg_Create. Invoking C# delegate.\n", stdout);
cb_is_my(1);
return NULL;
}
运行 应用程序写入以下消息:
C++. strg_Create. Invoked.
C++. strg_Create. Invoking C# delegate.
C#. sharpStaticMethod. Invoked.
C#. sharpStaticMethod. Zero division.
Unhandled exception. System.DivideByZeroException: Attempted to divide by zero.
at TestPlayground0806.NetProgram.Smth.sharpStaticMethod(Int32 id) in C:\Users\dev02\source\repos\TestPlayground0806\TestPlayground0806\NetProgram.cs:line 106
Aborted (core dumped)
结果:从非托管代码调用的 C# 函数中抛出异常,导致整个应用程序崩溃。我应该怎么做才能捕捉到这些异常?
更新: 异常在 Windows 10 上被捕获,但我无法在 CentOS 7 上捕获它。
It works that way on Windows because the Windows stack frames support the exception mechanism through non-managed frames. It does not work that way on Linux because the Linux stack frames do not support the exception mechanism through non-managed frames. – Eljay
问题的思路如下:我将 C# 函数指针传递给 C++ 编译库,然后从 C++ 调用传递的函数。我想从代码中捕获 C#/C++ 异常,代码位于 before C++ 函数调用。
问题的思路如下:我将 C# 函数指针传递给 C++ 编译库,然后从 C++ 调用传递的函数。我的 C++ 调用包含在 try/catch
中,我想从 C++/C# 函数中捕获异常。
所以,我有 .NET 5 应用程序,它运行以下代码:
class NetProgram
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void CustomCppFunc(int id);
[DllImport("/root/projects/LinuxLoop/bin/x64/Debug/libLinuxLoop.so")]
protected static extern void strg_Create(IntPtr cb_is_my);
static void Main(string[] args)
{
CustomCppFunc sharpDelegate = new CustomCppFunc(Smth.sharpStaticMethod);
try
{
strg_Create(Marshal.GetFunctionPointerForDelegate(sharpDelegate));
}
catch (Exception e)
{
Console.WriteLine("Catched exception from C# Program: " + e.Message);
}
finally
{
Console.WriteLine("Finally from C# Program.");
}
}
public class Smth
{
public static void sharpStaticMethod(IntPtr id)
{
Console.WriteLine("C#. sharpStaticMethod. Invoked.");
Console.WriteLine("C#. sharpStaticMethod. Zero division.");
var b = 0;
var a = 1 / b;
}
}
}
libLinuxLoop.so 是 Linux 的 C++ 编译库(我使用的是 CentOS 7),它有以下内容:
MyCppFunc.h:
#ifdef MYCPPFUNC
#define MYCPPFUNC __attribute__((dllexport))
#else
#define MYCPPFUNC __attribute__((dllimport))
#endif
typedef void(*CBIsMy)(int order_id);
extern "C" MYCPPFUNC void *strg_Create(CBIsMy cb_is_my);
MyCppFunc.cpp:
#include <cstdio>
#include <utility>
#include <limits.h>
#include "MyCppFunc.h"
void *strg_Create(CBIsMy cb_is_my) {
std::fputs("C++. strg_Create. Invoked.\n", stdout);
std::fputs("C++. strg_Create. Invoking C# delegate.\n", stdout);
cb_is_my(1);
return NULL;
}
运行 应用程序写入以下消息:
C++. strg_Create. Invoked.
C++. strg_Create. Invoking C# delegate.
C#. sharpStaticMethod. Invoked.
C#. sharpStaticMethod. Zero division.
Unhandled exception. System.DivideByZeroException: Attempted to divide by zero.
at TestPlayground0806.NetProgram.Smth.sharpStaticMethod(Int32 id) in C:\Users\dev02\source\repos\TestPlayground0806\TestPlayground0806\NetProgram.cs:line 106
Aborted (core dumped)
结果:从非托管代码调用的 C# 函数中抛出异常,导致整个应用程序崩溃。我应该怎么做才能捕捉到这些异常?
更新: 异常在 Windows 10 上被捕获,但我无法在 CentOS 7 上捕获它。
It works that way on Windows because the Windows stack frames support the exception mechanism through non-managed frames. It does not work that way on Linux because the Linux stack frames do not support the exception mechanism through non-managed frames. – Eljay