正确使用 Marshal.Copy

发布于 2024-08-27 21:07:23 字数 3983 浏览 6 评论 0原文

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

我的表单上有一个获取 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;
    }
}

I have a working wrapper class for Dallmeier camera devices, It contains a callback method to receive the current YUV image.
See details C# wrapper for array of three pointers.

I have a button on my form that gets the YUV Image. The callback returns 'yuvData' which is an array of three pointers to Y, U, and V part of image.
I then copy the three pointers into thier own pointer and then copy them into a byte array. The yuvCallback continues to run until I disconnect the camera.

Am I using Marshal.Copy correctly?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

ヤ经典坏疍 2024-09-03 21:07:23

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

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

I see you posted a similar question over at the MSDN forums: http://social.msdn.microsoft.com/Forums/en-US/clr/thread/67d20c16-d58b-444d-9689-88fab2792ab1

As I wrote over there, it's not correct to pack the callback delegate's parameters into a structure and pass it by value. So the first step is to correct the delegate signature.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文