将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#类
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;
答案 0 :(得分:3)
不,您不必,但是您必须固定它,因为允许GC在垃圾回收期间移动内存中的托管对象。
t
在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;
超出范围后,不应该使用指针,因为数据将不再固定,并且可能会被GC压缩移动。这是一个令人讨厌的错误,等待发生。
如果您需要长期固定,请使用固定rawDataPinned
:
GCHandle
它通过GCHandle::Alloc(rawImage->RawData, GCHandleType::Pinned)
向第一个数组项提供void*
使用后别忘了handle->AddrOfPinnedObject().ToPointer()
。
这比Free()
更重要,因为它需要在GC中注册一个句柄,而pin_ptr
只有在你的对象被固定时发生一个集合时才会被GC注意到它 - &# 39;尽可能轻松。