非托管内存中的byte []数组

时间:2015-08-03 11:35:07

标签: c# c++ mono bytearray pinvoke

我正在monodevelop中为linux(Ubuntu)下的Basler相机编写一个简单的.NET包装器到C / C ++ Pylon库。我在Code :: Blocks中构建一个.so(.dll)文件,并在monodevelop中调用它。 我有两个简单的任务:获取单个图像并获得一系列图像。

我用这种方式管理了第一部分:

在C ++中我有一个函数:

void GetImage(void* ptr)
{
    CGrabResultPtr ptrGrabResult;
    //here image is grabbing to ptrGrabResult
    camera.GrabOne(5000,ptrGrabResult,TimeoutHandling_ThrowException);
    //i'm copying byte array with image to my pointer ptr
    memcpy(ptr,ptrGrabResult->GetBuffer(),_width*_height);

    if (ptrGrabResult->GrabSucceeded())
        return;
    else
        cout<<endl<<"Grab Failed;"<<endl;
}

并在C#中:

[DllImport("libPylonInterface.so")]
private static extern void GetImage(IntPtr ptr);

public static void GetImage(out byte[] arr)
{
    //allocating unmanaged memory for byte array
    IntPtr ptr = Marshal.AllocHGlobal (_width * _height);
    //and "copying" image data to this pointer
    GetImage (ptr);

    arr = new byte[_width * _height];
    //copying from unmanaged to managed memory
    Marshal.Copy (ptr, arr, 0, _width * _height);
    Marshal.FreeHGlobal(ptr);
}

之后我可以从这个byte[] arr建立一个图像。

我必须复制大量的字节两次(1.c ++ memcpy(); 2. c#Marshal.Copy())。我试图使用直接指向图像缓冲区ptr = ptrGrabResult -> GetBuffer()的指针,但在编组字节时会出现单声道环境错误。

所以这是一个问题:这是一个很好的解决方案吗?我正朝着正确的方向前进吗?

P.S。请给我一些建议如何处理图像序列?

1 个答案:

答案 0 :(得分:2)

您可以让编组人员为您完成工作。像这样:

[DllImport("libPylonInterface.so")]
private static extern void GetImage([Out] byte[] arr);

....

arr = new byte[_width * _height];
GetImage(arr);

这避免了第二个内存复制,因为编组器将固定托管阵列并将其地址传递给非托管代码。然后,非托管代码可以直接填充托管内存。

第一份副本看起来更难以避免。这可能是您正在使用的相机库强制要求的。我会评论说,如果抓取成功,你应该只执行该副本。