微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

从非托管 C++ 代码调用 C# 函数时无法处理异常

如何解决从非托管 C++ 代码调用 C# 函数时无法处理异常

问题的想法如下:我将 C# 函数指针传递给 C++ 编译库,然后从 C++ 调用传递的函数。我想从代码中捕获 C#/C++ 异常,它位于之前 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# 函数抛出异常,由非托管代码调用,导致整个应用程序崩溃。我应该怎么做才能捕获这些异常?

UPD:异常在 Windows 10 上被捕获,但在 CentOS 7 上我无法捕获。

解决方法

它在 Windows 上是这样工作的,因为 Windows 堆栈框架通过非托管框架支持异常机制。它在 Linux 上不能那样工作,因为 Linux 堆栈帧不支持通过非托管帧的异常机制。 – 艾尔杰

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?