试图使用clr dll但无法从c#调用方法

时间:2014-04-17 08:19:44

标签: c# c++-cli clr

我有一个我试图从c#访问的c函数库。我已经尝试过PInvoke路由但是有一些包含可变长度数组的结构,所以这种方法不起作用,我被建议尝试c ++ / cli。在查看之后(并提出了更多问题)我已经为我的一个c函数创建了一个包装类。 c函数的输入是一个结构,它包含两个双数组和一个数组的长度(另一个是固定大小),以及一个double。我能够为我的包装器创建一个小测试应用程序(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. 在输入中添加另一个double []并填充该
  3. 返回双[]

1 个答案:

答案 0 :(得分:2)

为什么让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-&gt; Length。如有必要,您可以在C ++ / CLI代码中使用pin_ptr<>来获取本机代码可以使用的double*。小心,它只是暂时固定。