我有一个C ++库,我正在编写C#包装器。 我坚持将数组传递给unmanaged并在.NET中读回来。
我想要的是一个包装器函数,它将浮点数组作为参数(托管),在非托管函数中处理它并将其作为托管数组返回。
现在我通过创建C ++数组,将值从托管复制到非托管,然后将其作为参数传递给本机函数调用来实现。之后,我必须将结果复制回来将其发送回托管代码。
这是我目前的做法:
array<float>^ Process(int samplesCount, array<float>^ audiodata){
float* audioData[1];
//copying to unmanaged
audioData[0] = new float[samplesCount];
for (int i = 0; i < samplesCount; ++i){
audioData[0][i] = audiodata[i];
}
//process unmanaged
//int numSamples //float *const *arrayOfChannels
_filter->process(samplesCount, audioData);
//copying back from unmanaged
array<float> ^result = gcnew array<float>(samplesCount);
for (int i = 0; i < samplesCount; ++i){
result[i] = audioData[0][i];
}
return result;
}
问题是,_filter-&gt; process()函数将float * const * arrayOfChannels作为第二个参数,这对我来说是最困难的。 所以它会接受这样的事情:
// create a two channel audio buffer
int numSamples = 2000;
float* audioData[2];
audioData[0] = new float[numSamples];
audioData[1] = new float[numSamples];
// and somewhere after:
_filter->process (numSamples, audioData);
是否有可能在不复制数组的情况下从托管世界传递float *const *arrayOfChannels
参数?
答案 0 :(得分:2)
是的,您无需复制即可完成此操作。使用pin_ptr获取指向您的托管数据的普通float*
,然后将该指针放入您需要的任何结构中。
请注意,通过将托管数组传递给非托管代码,您最终将更改为Process
方法传递的参数:非托管代码正在修改传递给它的数组,并且因为您和#39;将托管数组传递给非托管代码,这是您在托管代码中最终得到的内容。 Process
将更改为返回void
,并修改输入数组的内容。
另请注意,如果在固定阵列时发生垃圾收集,垃圾收集器必须执行额外的工作,因为它不再允许移动内存。因此,您希望将数组固定在尽可能短的时间内,只需要足够长的时间来调用非托管方法。
void Process(array<float>^ channel1, array<float>^ channel2)
{
pin_ptr<float> pinned1 = &channel1[0];
float* asPointer1 = pinned1;
pin_ptr<float> pinned2 = &channel2[0];
float* asPointer2 = pinned2;
float* audioData[2];
audioData[0] = asPointer1;
audioData[1] = asPointer2;
_filter->process(channel1->Length, audioData);
}