[英]passing 2D array from C# to unmanaged C++ using C++/CLI wrapper
[英]Passing a C# double array to a C++ function using CLI
我在C#中有一些GUI代码(请注意,我以前从未使用过C#,但是熟悉语法),并且我有C ++代码,可以使用CLI与之交互。
在C#中,我想创建一个双精度数组,并将其发送到我的C ++代码。 我使用下面的代码作为传递数组的方法,并且这是隔离的。
因此,从C#im中将double []数组传递给该函数。
public ref class KernelWrapper
{
public:
static void ImageNoiseFilter(System::IntPtr imageData, int imageWidth, int imageHeight, array<double>^ values);
我应该使用哪种参数类型从C ++端检索此数组?
我试过了:
MyFunction(double values[]){}
MyFunction(double* values){}
MyFunction(array<double>^ values){}
但没有一个可以编译,通常最后一个消息是“数组不是模板”,并且
Error 1 error C2664: 'RunImageNoiseFilterKernel' : cannot convert parameter 4 from 'cli::array<Type> ^' to 'double *'
任何有关如何实现此目的的技巧将不胜感激。
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.
}
double[] randomValues = new double[ARRAY_LENGTH]; //Array of random numbers
KernelWrapper.ImageNoiseFilter(ptr, image.Width, image.Height, randomValues);
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*'
希望这可以澄清一点。
您应该使用pin_ptr <>类将托管数组转换为double *。 它固定了数组,因此当您的本机函数正在执行和访问数组数据时,垃圾收集器无法移动它。
#include <vcclr.h> // Declares cli::pin_ptr<>
using namespace cli;
#pragma managed(push, off)
# include "unmanagedstuff.h" // Declaration of MyFunction here
#pragma managed(pop)
...
pin_ptr<double> pvalues = &values[0];
MyFunction(pvalues, values->Length);
假设MyFunction()当然也需要知道数组的大小,因此我添加了一个额外的参数来传递数组的大小。 不这样做会致命,您的本机代码可能会破坏托管堆的完整性。 请注意,只有在pvalues在作用域内时,数组才会保持固定状态,因此MyFunction() 不要存储传递的指针很重要。 如果是这种情况,则必须复制该阵列。
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Linq;
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);
static void ImageNoiseFilter(System::IntPtr imageData, int imageWidth, int imageHeight, System::IntPtr randValPtr);
void KernelWrapper::ImageNoiseFilter(System::IntPtr imageData, int imageWidth, int imageHeight, System::IntPtr randValues){
RunImageNoiseFilterKernel((Format24bppRgb*)((int)imageData), imageWidth, imageHeight, (float*) ((int) randValues));
}
所有这些似乎都可以正常工作:),我不知道这种方法有多好或多么安全,因此任何阅读此方法的人都不应假定其是“正确”的方法,它才有效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.