【发布时间】:2016-03-05 23:34:51
【问题描述】:
我有一个 C++ 函数,它接受一个数组 (double*) 作为参数,对数据进行处理并返回一个指向相同数据的 complex* 类型的指针。我需要使用 c++/cli 包装这个函数,但我不确定如何确保 .NET 最终得到对内存的正确引用。例如,如果用户像 Complex[] data = Process(new double[1024]); 这样调用函数,我想确保在函数返回时数据不会被垃圾收集(并且我的 pin_ptr 超出范围)并且它确实在data 超出范围。
我怎样才能得到两个对内存的有效引用,每个引用都不同?
注意:底层 C++ 函数工作正常,这是一个 .NET C++/CLI 问题,关于如何获取对同一内存的两个垃圾收集引用,两种不同类型。
#pragma unmanaged
complex<double>* NativeFft(double* real_time_data, int data_size) {
// do in-place FFT on data (no allocations)
return reinterpret_cast<complex<double*>>(real_time_data);
}
#pragma managed
array<Complex>^ Transform::Fft(array<double>^ real_time_data) {
if (real_time_data== nullptr) {
throw gcnew ArgumentNullException("'real_time_data' must not be null");
}
int data_size = real_time_data->Length;
pin_ptr<double> data_ptr = &real_time_data[0];
complex<double>* complex_freq_data = NativeFft(data_ptr, data_size);
// now how do I make another reference to the data?
// (I also need the Length field to be halved).
array<Complex>^ managed_complex_freq_data = ???
return managed_complex_freq_data;
}
编辑: 这是更多信息,因为每个人都说明显的解决方案是复制数据。 我正在做的是一个非常大的从实到复杂的原位 FFT。数据以双精度数组的形式出现,并且基本上保持这种状态(显然值会发生变化),但是在 FFT 完成后,对数据的正确解释是每对双精度都构成单精度的实部和虚部复杂的样本。我想做的 FFT 的大小对于 32 位系统来说太大了,但我不想尽可能接近它,所以我不想牺牲做副本所需的内存数据。我可以始终将数据作为双精度来处理,但能够将其视为复杂的会很好,因为这就是 FFT 之后的真实情况。
【问题讨论】:
-
它是托管类型 (
^),所以您不要这样做。请阅读What is the XY problem? 并相应地更改您的问题。 -
new double[1024]应该在函数返回后收集垃圾,因为它不再需要。返回值应该从data_out构建(在调用NativeProcess之后,您已经完成了data,所以不知道为什么您认为需要使用相同的“内存”)。 -
我需要使用相同的内存,因为数组会尽可能大,即使原始数组被销毁,我也没有空间将它复制到另一个数组,因为对于片刻之后,两个数组都将存在,我将耗尽内存。