使用CLI将C#double数组传递给C++函数

Bla*_*Box 5 c# c++ arrays pointers c++-cli

对,需要听起来很简单,但事实证明这是一个真正的痛苦.

我在C#中有一些GUI代码(注意我以前从未使用过C#但熟悉语法)并且我有使用CLI与之交互的C++代码.

在C#中,我想创建一个双精度数组,并将其发送到我的C++代码.我使用下面的代码作为传递数组的方法,这是孤立的.

所以从C#im传入double []数组到该函数.

public ref class KernelWrapper
{
public: 
    static void ImageNoiseFilter(System::IntPtr imageData, int imageWidth, int imageHeight, array<double>^ values); 
Run Code Online (Sandbox Code Playgroud)

我应该使用什么参数类型从C++端检索此数组?

我试过了:

 MyFunction(double values[]){}
 MyFunction(double* values){}
 MyFunction(array<double>^ values){} 
Run Code Online (Sandbox Code Playgroud)

但没有编译,通常使用"数组不是模板"的消息,最后一个,和

Error   1   error C2664: 'RunImageNoiseFilterKernel' : cannot convert parameter 4 from 'cli::array<Type> ^' to 'double *'
Run Code Online (Sandbox Code Playgroud)

关于如何实现这一目标的任何提示将不胜感激.


为了便于阅读,我在这里用代码更新

.cpp文件:

void Bangor::KernelWrapper::ImageNoiseFilter(System::IntPtr imageData, int imageWidth,    int imageHeight, pin_ptr<double> pval){
    RunImageNoiseFilterKernel((Format24bppRgb*)((int)imageData), imageWidth, imageHeight); //If parameter would work, 4th argument would also be passed into this.
}
Run Code Online (Sandbox Code Playgroud)

C#代码:

    double[] randomValues = new double[ARRAY_LENGTH]; //Array of random numbers
    KernelWrapper.ImageNoiseFilter(ptr, image.Width, image.Height, randomValues);
Run Code Online (Sandbox Code Playgroud)

错误是:

Error   1   error C3824: 'cli::pin_ptr<Type>': this type cannot appear in this context (function parameter, return type, or a static member)
Error   3   The best overloaded method match for 'Bangor.KernelWrapper.ImageNoiseFilter(System.IntPtr, int, int, double*)' has some invalid arguments   
Error   4   Argument 4: cannot convert from 'double[]' to 'double*' 
Run Code Online (Sandbox Code Playgroud)

希望这澄清一点.

Bla*_*Box 2

好吧,大多数尝试对我来说都失败了;可能是因为我做错了:P,但这里有一个可行的解决方案。

进口:

using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Linq;
Run Code Online (Sandbox Code Playgroud)

在 C# 文件中,我创建一个数组,如下所示:

    float[] randomValues = new float[ARRAY_LENGTH]; //Array of random numbers
    GCHandle handle = GCHandle.Alloc(randomValues, GCHandleType.Pinned);
    var randPtr = handle.AddrOfPinnedObject();
    KernelWrapper.ImageNoiseFilter(ptr, image.Width, image.Height, randPtr);
Run Code Online (Sandbox Code Playgroud)

ImageNoiseFilter的定义是:

static void ImageNoiseFilter(System::IntPtr imageData, int imageWidth, int imageHeight, System::IntPtr randValPtr);
Run Code Online (Sandbox Code Playgroud)

为了在我的 C++ 函数中获取需要浮点指针的内容,我这样做:

void KernelWrapper::ImageNoiseFilter(System::IntPtr imageData, int imageWidth, int imageHeight, System::IntPtr randValues){
    RunImageNoiseFilterKernel((Format24bppRgb*)((int)imageData), imageWidth, imageHeight, (float*) ((int) randValues));
}
Run Code Online (Sandbox Code Playgroud)

所有这一切似乎都工作正常:),我不知道这种方法有多好或多安全,所以阅读本文的任何人都不应该假设它是“正确”的方法,它只是有效。