我有一个 Dallmeier 相机设备的工作包装类,它包含一个回调方法来接收当前的 YUV 图像。
查看详情 C# wrapper for array of three pointers .
我的表单上有一个获取 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
正如我在那里写的那样,将回调委托(delegate)的参数打包到一个结构中并按值传递它是不正确的。所以第一步是更正代表签名。
关于c# - 正确使用 Marshal.Copy,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2559308/