访问.NET ushort []数组作为uint16_t *而不复制

时间:2015-10-12 21:24:02

标签: .net visual-c++ c++-cli native mixed-mode

将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;

1 个答案:

答案 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;尽可能轻松。