c++cli-尝试使用clr dll,但无法从c#调用方法

本文关键字:方法 调用 dll clr c++cli- | 更新日期: 2023-09-27 17:58:47

我有一个c函数库,我正试图从c#访问它。我尝试过PInvoke路由,但有一些结构包含可变长度数组,所以这种方法不起作用,建议我尝试c++/cli。经过研究(并问了更多的问题),我为我的一个c函数创建了一个包装器类。c函数的输入是一个结构,它包含两个双数组和其中一个数组的长度(另一个是固定大小的),以及一个双数组。我能够为我的包装器创建一个小的测试应用程序(clr控制台),这样我就知道它在调用c代码并做它应该做的事情,我现在只需要弄清楚如何从c#调用它。由于它现在是一个托管dll,我已经将它添加到我的引用中,我可以将它放在代码中,但方法签名已经将数组转换为指针,这是我在c#中无法做到的。我试着使用ref来处理数组,但不知道如何使其工作。

c++签名:

static void test_wrapper(double prefix[], double arr[], int arrayLength, double value);

所以当我在c中调用它时:

Test_Wrapper_Class.test_wrapper(???, ???, array.Length, 2.2);

然而???这表明它期待着双冠王,我不太确定该怎么办。

对于奖励积分,我想返回一个双数组,但不确定用哪种方式。选项是:

  1. 只需重用arr,因为返回的数组大小相同
  2. 在输入中再添加一个双[]并填充该双[]
  3. 返回双[]

c++cli-尝试使用clr dll,但无法从c#调用方法

不太清楚为什么让C#很难使用您的函数。请记住,C++/CLI语言允许您使用托管或非托管阵列。您现在使用的是非托管数组作为参数,因此C#代码很难调用该函数。使用不安全代码并非不可能:

    static unsafe void Main(string[] args) {      // NOTE unsafe keyword
        var arg1 = new double[] { 1, 2, 3 };
        var arg2 = new double[] { 4, 5, 6 };
        fixed (double* arg1ptr = arg1)
        fixed (double* arg2ptr = arg2) {
            Test_Wrapper_Class.test_wrapper(arg1ptr, arg2ptr, arg1.Length, 42.0);
        }
    }

注意C#代码需要如何使用unsafe关键字。它是如何真正不安全的,你没有包括一个参数,说明第二个数组有多长,这样本机代码就可以很容易地在GC堆中乱写并损坏它。

但当您将参数声明为托管数组时,这是不必要的:

static void test_wrapper(array<double>^ prefix, array<double>^ arr, double value);

安全且易于从C#调用。请注意,您不再需要传递数组长度参数,您已经从prefix->length中知道了它。如果需要,可以使用pin_ptr<>在您的C++/CLI代码中,以获得本机代码可以使用的double*。小心,它只是暂时固定的。