正确使用Marshal.Copy

我有一个用于Dallmeier相机设备的工作包装器类,它包含一个接收当前YUV图像的回调方法。
有关三个指针的数组,请参阅C#wrapper的详细信息。

我的表单上有一个按钮,可以获取YUV图像。 回调返回’yuvData’,它是一个三个指向Y,U和V部分图像的数组。 然后我将三个指针复制到他们自己的指针中,然后将它们复制到一个字节数组中。 yuvCallback继续运行,直到我断开相机。

我正确使用Marshal.Copy吗?

public class DLMSDK { public delegate int YUVDataCallback(dlm_yuvdataParametersStructure pParameters); DllImport(@"DallmeiersDLL\davidapileolive.dll")] public extern static int dlm_setYUVDataCallback(int SessionHandle, YUVDataCallback dataCallback); [StructLayout(LayoutKind.Explicit, Size = 32)] public struct dlm_yuvdataParametersStructure { [FieldOffset(0)] public int IPlayerID; [FieldOffset(4), MarshalAs(UnmanagedType.ByValArray, SizeConst=3)] public IntPtr[] yuvData; [FieldOffset(8), MarshalAs(UnmanagedType.ByValArray, SizeConst=1)] public IntPtr[] pitch; [FieldOffset(12)] public int width; [FieldOffset(16)] public int height; [FieldOffset(18)] public long ts; [FieldOffset(28), MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] public IntPtr[] extData; } } public partical class Form1 : Form { int width; int height; int yArraySize; int uvArraySize; byte[] yBytes; byte[] uBytes; byte[] vBytes; int sizeY; int sizeU; int sizeV; IntPtr ptrY; IntPtr ptrU; IntPtr ptrV; DLMSDK.YuvDataCallback yuvdataCallback; private void Form1_Load(object send, EventArgs e) { error = DLMSDK.dlm_initSDK(); if (error == 0) registerEvents(); } private void registerEVents() { yuvdataCallback = yuvdataHandler; } private void btnGetYUV_Click(object sender, EventArgs e) { try { error = DLMSDK.dlm_setYUVDataCallback(SessionHandle, yuvdataCallback); } catch (Exception ex) { MessageBox.Show(ex.ToString()); } } public int yuvdataHandler(DLMSDK.dlm_yuvdataParametersStructure pParameters) { width = pParameters.width; height = pParameters.height; yArraySize = width * height; uvArraySize = yArraySize/4; yBytes = new byte[yArraySize]; uBytes = new byte[uvArraySize]; vBytes = new byte[uvArraySize]; sizeY = Marshal.SizeOf(yBytes[0]) * yBytes.Length; ptrY = Marshal.AllocHGlobal(sizeY); sizeU = Marshal.SizeOf(uBytes[0]) * uBytes.Length; ptrU = Marshal.AllocHGlobal(sizeU); sizeV = Marshal.SizeOf(vBytes[0]) * vBytes.Length; ptrV = Marshal.AllocHGlobal(sizeV); try { // Copy the three pointers to Y,U, & V pointers Marshal.Copy(pParameters.yuvData, 0, ptrY, 1); Marshal.Copy(pParameters.yuvData, 1, ptrU, 1); Marshal.Copy(pParameters.yuvData, 2, ptrV, 1); // Copy pointers to YUV byte arrays Marshal.Copy(ptrY, yBytes, 0, sizeY); Marshal.Copy(ptrU, uBytes, 0, sizeU); Marshal.Copy(ptrV, vBytes, 0, sizeV); // Convert Y (Luminance) to Greyscale and display Bitmap bmp = ImgConvert.ToGreyscale(yBytes, width, height); DisplayImage(bmp); } finally { if (ptrY != IntPtr.Zero) { Marshal.FreeHGlobal(ptrY); ptrY = IntPtr.Zero; } if (ptrU != IntPtr.Zero) { Marshal.FreeHGlobal(ptrU); ptrU = IntPtr.Zero; } if (ptrV != IntPtr.Zero) { Marshal.FreeHGlobal(ptrV); ptrV = IntPtr.Zero; } } return 0; } } 

我看到你在MSDN论坛上发布了类似的问题: http : //social.msdn.microsoft.com/Forums/en-US/clr/thread/67d20c16-d58b-444d-9689-88fab2792ab1

正如我在那里写的那样,将回调委托的参数打包到结构中并按值传递是不正确的。 所以第一步是纠正委托签名。