以 uint16_t* 形式访问 .NET ushort[] 数组而不复制
Access .NET ushort[] array as uint16_t* without copying
将 ushort[] 从 c# 转换为 c++/cli 转换为 c++ 时,是否必须复制所有数据?或者我可以投指针吗?
PreprocessorWrapper::Function1(ImageData^ rawImage)
{
array<unsigned short>^ rawDataTemp = rawImage->RawData;
bayer_raw_image* inputImage = new bayer_raw_image();
inputImage->raw_data = (uint16_t*)rawDataTemp; //error is here
}
这是我遇到的错误
error C2440: 'type cast' : cannot convert from 'cli::array<Type> ^' to 'uint16_t
这是 C# class
public class ImageData
{
public int WidthColumns { get; set; }
public int HeightLines { get; set; }
public ushort[] RawData { get; set; }
public ushort BitDepth { get; set; }
}
c++ class
typedef struct
{
uint16_t width;
uint16_t height;
uint16_t* raw_data;
uint16_t bit_depth;
} bayer_raw_image;
不,您不必这样做,但您必须固定它,因为允许 GC 在垃圾收集期间移动内存中的托管对象。
array<uint16_t>^ rawDataTemp = rawImage->RawData;
pin_ptr<uint16_t> rawDataPinned = &rawDataTemp[0];
bayer_raw_image* inputImage = new bayer_raw_image();
inputImage->raw_data = rawDataPinned;
你应该不在rawDataPinned
超出范围后使用指针,因为数据将不再被固定并且会被移动通过 GC 压缩。这是一个等待发生的讨厌的错误。
如果您需要长期固定,请使用固定 GCHandle
:
GCHandle::Alloc(rawImage->RawData, GCHandleType::Pinned)
它通过handle->AddrOfPinnedObject().ToPointer()
为第一个数组项提供void*
。
使用后别忘了Free()
。
这比 pin_ptr
更重量级,因为它需要在 GC 中注册一个句柄,而 pin_ptr
只有在您的对象被固定时发生收集时才会被 GC 注意到 -它尽可能轻便。
将 ushort[] 从 c# 转换为 c++/cli 转换为 c++ 时,是否必须复制所有数据?或者我可以投指针吗?
PreprocessorWrapper::Function1(ImageData^ rawImage)
{
array<unsigned short>^ rawDataTemp = rawImage->RawData;
bayer_raw_image* inputImage = new bayer_raw_image();
inputImage->raw_data = (uint16_t*)rawDataTemp; //error is here
}
这是我遇到的错误
error C2440: 'type cast' : cannot convert from 'cli::array<Type> ^' to 'uint16_t
这是 C# class
public class ImageData
{
public int WidthColumns { get; set; }
public int HeightLines { get; set; }
public ushort[] RawData { get; set; }
public ushort BitDepth { get; set; }
}
c++ class
typedef struct
{
uint16_t width;
uint16_t height;
uint16_t* raw_data;
uint16_t bit_depth;
} bayer_raw_image;
不,您不必这样做,但您必须固定它,因为允许 GC 在垃圾收集期间移动内存中的托管对象。
array<uint16_t>^ rawDataTemp = rawImage->RawData;
pin_ptr<uint16_t> rawDataPinned = &rawDataTemp[0];
bayer_raw_image* inputImage = new bayer_raw_image();
inputImage->raw_data = rawDataPinned;
你应该不在rawDataPinned
超出范围后使用指针,因为数据将不再被固定并且会被移动通过 GC 压缩。这是一个等待发生的讨厌的错误。
如果您需要长期固定,请使用固定 GCHandle
:
GCHandle::Alloc(rawImage->RawData, GCHandleType::Pinned)
它通过handle->AddrOfPinnedObject().ToPointer()
为第一个数组项提供void*
。
使用后别忘了Free()
。
这比 pin_ptr
更重量级,因为它需要在 GC 中注册一个句柄,而 pin_ptr
只有在您的对象被固定时发生收集时才会被 GC 注意到 -它尽可能轻便。