使用CLI将c#双精度数组传递给c++函数
Passing a C# double array to a C++ function using CLI
是的,需要做的事情听起来很简单,但事实证明这是一个真正的痛苦。
我在 c# 中有一些GUI代码(注意我以前从未使用过c#,但熟悉语法),我有 c++ 代码,使用CLI与之交互。
在c#中,我想创建一个双精度数组,并将其发送到我的c++代码中。我使用下面的代码作为传递数组的方法,并且这是单独执行的。所以在c#中,我将一个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){}
但是没有编译,通常最后一个会显示"array is not a template"的信息,而
Error 1 error C2664: 'RunImageNoiseFilterKernel' : cannot convert parameter 4 from 'cli::array<Type> ^' to 'double *'
如果有任何关于如何做到这一点的建议,我将不胜感激。
为了可读性,我在这里更新了代码
<标题> . 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.
}
<标题> c#代码: 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<>类将托管数组转换为双精度*。它固定数组,所以垃圾收集器不能在本机函数执行和访问数组数据时移动它。
#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()不存储传入的指针是很重要的。如果是这种情况,那么必须复制数组。
好吧,所以我的大多数尝试都失败了;可能是因为我做错了:P,但这里有一个解决方案确实有效。
进口:
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Linq;
在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);
ImageNoiseFilter的定义为:
static void ImageNoiseFilter(System::IntPtr imageData, int imageWidth, int imageHeight, System::IntPtr randValPtr);
要在我的c++函数中获得一个浮点指针,我这样做:
void KernelWrapper::ImageNoiseFilter(System::IntPtr imageData, int imageWidth, int imageHeight, System::IntPtr randValues){
RunImageNoiseFilterKernel((Format24bppRgb*)((int)imageData), imageWidth, imageHeight, (float*) ((int) randValues));
}
所有这些似乎都很好:),这种方法有多好或安全我不知道,所以任何读到这篇文章的人都不应该认为这是"正确"的方法,它只是有效的。
相关文章:
- "error: no matching function for call to"构造函数错误
- 什么时候调用组成单元对象的析构函数
- 继承函数的重载解析
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- C++模板来检查友元函数的存在
- 递归函数计算序列中的平方和(并输出过程)
- 对RValue对象调用的LValue ref限定成员函数
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 为什么使用 "this" 指针调用派生成员函数?
- 将对象数组的引用传递给函数
- 函数调用中参数的顺序重要吗
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用不带参数的函数访问结构元素
- 代码在main()中运行,但在函数中出现错误
- 内置函数可查看CPP中的成员变量
- 如何获取std::result_of函数的返回类型
- 如何在c++中为模板函数实例创建快捷方式
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗