gaerelva 2024-07-30 12:52 采纳率: 90.9%
浏览 7
已结题

c#调用c++方法提示错误 无法封送处理泛型类型

报错语句 int n = NonLinearEquation_dhrt(ptr, -2.0, 5.0, 0.2, 0.000001, x, m, MyFunction);

运行时:无法封送处理“parameter #8”: 无法封送处理泛型类型。
如何解决这种问题?


using System;
using System.Runtime.InteropServices;
class Program {
    [DllImport("your_dll_name.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern IntPtr NonLinearEquation_create();
    [DllImport("your_dll_name.dll", CallingConvention = CallingConvention.Cdecl)]
    public static extern int NonLinearEquation_dhrt(IntPtr ptr, double a, double b, double h, double eps, double[] x, int m, Func<double, double> f);
    static double MyFunction(double x) {
        return (((((x - 5.0) * x + 3.0) * x + 1.0) * x - 7.0) * x + 7.0) * x - 20.0;
    }
    static void Main() {
        IntPtr ptr = NonLinearEquation_create();
        int m = 6;
        double[] x = new double[m];
        int n = NonLinearEquation_dhrt(ptr, -2.0, 5.0, 0.2, 0.000001, x, m, MyFunction);
        Console.WriteLine("根的个数 = " + n);
        for (int i = 0; i < n; i++) {
            Console.WriteLine("x(" + i + ") = " + x[i]);
        }
    }
}

  • 写回答

1条回答 默认 最新

  • 才华横溢caozy 2024-07-30 15:33
    关注

    此答案是由GPT4和本人亲自作答,如有帮助,还请采纳!
    你遇到的错误是因为无法封送处理 C# 中的泛型类型 Func<double, double>。这是因为 C# 和 C++ 之间的 P/Invoke 机制不支持直接传递委托给非托管代码。要解决这个问题,可以采用以下步骤:

    1. 定义一个非托管函数指针类型:在 C++ 代码中定义一个函数指针类型。
    2. 创建一个包装器:在 C++ 代码中创建一个包装器函数,该函数接受函数指针作为参数。
    3. 导出包装器函数:使用 extern "C" 导出包装器函数。
    4. 在 C# 中声明函数指针类型:使用 UnmanagedFunctionPointer 属性声明函数指针类型。
    5. 将 C# 委托转换为函数指针:在调用 C++ 函数时,将 C# 的委托转换为函数指针。

    下面是具体的实现步骤和代码示例:

    1. 在 C++ 中定义函数指针类型和包装器函数

    首先,在 C++ 中定义一个函数指针类型和一个包装器函数,该函数将接收一个函数指针作为参数。

    // your_cpp_code.cpp
    
    extern "C" {
        typedef double (*FuncPointer)(double);
    
        __declspec(dllexport) int NonLinearEquation_dhrt_wrapper(
            void* ptr, double a, double b, double h, double eps, double* x, int m, FuncPointer f);
    }
    
    int NonLinearEquation_dhrt_wrapper(
        void* ptr, double a, double b, double h, double eps, double* x, int m, FuncPointer f) {
        // 调用原始的 NonLinearEquation_dhrt 函数,传递函数指针 f
        return NonLinearEquation_dhrt(ptr, a, b, h, eps, x, m, f);
    }
    

    2. 在 C# 中声明非托管函数指针类型和包装器函数

    在 C# 中,使用 UnmanagedFunctionPointer 属性声明函数指针类型,然后声明包装器函数。

    using System;
    using System.Runtime.InteropServices;
    
    class Program {
        [DllImport("your_dll_name.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr NonLinearEquation_create();
    
        [DllImport("your_dll_name.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int NonLinearEquation_dhrt_wrapper(
            IntPtr ptr, double a, double b, double h, double eps, double[] x, int m, FunctionPointer f);
    
        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        public delegate double FunctionPointer(double x);
    
        static double MyFunction(double x) {
            return (((((x - 5.0) * x + 3.0) * x + 1.0) * x - 7.0) * x + 7.0) * x - 20.0;
        }
    
        static void Main() {
            IntPtr ptr = NonLinearEquation_create();
            int m = 6;
            double[] x = new double[m];
            FunctionPointer myFuncPointer = new FunctionPointer(MyFunction);
            int n = NonLinearEquation_dhrt_wrapper(ptr, -2.0, 5.0, 0.2, 0.000001, x, m, myFuncPointer);
            Console.WriteLine("根的个数 = " + n);
            for (int i = 0; i < n; i++) {
                Console.WriteLine("x(" + i + ") = " + x[i]);
            }
        }
    }
    

    解释

    1. 函数指针类型声明:使用 [UnmanagedFunctionPointer(CallingConvention.Cdecl)] 声明函数指针类型 FunctionPointer
    2. 包装器函数:在 C++ 中定义 NonLinearEquation_dhrt_wrapper 函数,接受一个函数指针类型 FuncPointer 作为参数。这个函数调用原始的 NonLinearEquation_dhrt 函数,并将函数指针传递给它。
    3. 导出包装器函数:使用 __declspec(dllexport) 导出 NonLinearEquation_dhrt_wrapper 函数,以便它可以被 C# 调用。
    4. 调用 C++ 函数:在 C# 中,将委托 MyFunction 转换为函数指针 myFuncPointer,并将其传递给包装器函数 NonLinearEquation_dhrt_wrapper

    通过这种方式,你可以将 C# 中的委托传递给 C++ 代码,并解决“无法封送处理泛型类型”的问题。这种方法的可行性高,并且解决方案具有很强的逻辑性。希望这个解决方案对你有帮助。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 系统已结题 8月7日
  • 已采纳回答 7月30日
  • 赞助了问题酬金15元 7月30日
  • 创建了问题 7月30日

悬赏问题

  • ¥20 校园二手交易小程序搭建
  • ¥15 请问在ubuntu用conda创建环境报错怎么能解决
  • ¥15 STM32CubeMX/proteus按键控制指示灯颜色切换
  • ¥20 python,计算区位熵和扩张指数
  • ¥15 Python环境配置
  • ¥15 大四学生的困惑,有偿提问!
  • ¥15 解决页面无法编入索引:被“noindex”标签排除的问题?
  • ¥15 arduino测量电阻
  • ¥15 快手uid转快手号谁能解决 需要开发
  • ¥15 iis部署Django时css不生效,来个真人,ai不好使