簡體   English   中英

Marshal.StructureToPtr InvalidCastException

[英]Marshal.StructureToPtr InvalidCastException

嘗試將結構設置為指針時出現非常奇怪的錯誤...拋出了無效的強制轉換異常,我對為什么完全感到困惑。 該函數要求提供3個參數,一個對象,IntPtr和一個布爾標志。 我正在設置的所有內容……甚至明確地將其強制轉換為沒有區別。 對象是結構,Intptr是指針並具有數據,並且標志僅設置為false。

有人在這種情況下收到過invalidcastexception嗎?

編輯

internal class FrameTransport
{
    #region Fields
    internal SharedMemoryChannel controlChannel;
    internal ControlChannelStruct controlStruct;
    internal SharedMemoryChannel frameChannel1;
    internal SharedMemoryChannel frameChannel2;
    internal byte[] bitmapData;
    internal int bitmapDataSize;
    internal uint sharedInfoSize;
    internal bool haveFrame;
    internal int height;
    internal int width;
    #endregion


    #region Structures
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    internal struct FrameChannelStruct
    {
        public Int32 bufid;
        public Int32 size;
        public Int32 width;
        public Int32 height;
        public Int32 bitsperpixel;
        public Int32 fourcc;
        public Int32 orientation;
        public Int64 clientpointer;
    };

    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    internal struct ControlChannelStruct
    {
        public Int32 bufferstates;
        public FrameChannelStruct buffer1;
        public FrameChannelStruct buffer2;
        public BufferType buftype;
        public Int32 configuration;
        public Int32 fourcccount;
        public Int32 fourcc01;
        public Int32 fourcc02;
        public Int32 fourcc03;
        public Int32 fourcc04;
        public Int32 fourcc05;
        public Int32 fourcc06;
        public Int32 fourcc07;
        public Int32 fourcc08;
        public Int32 fourcc09;
        public Int32 fourcc10;
    };
    #endregion


    #region Constructors
    /// <summary>
    /// Constructor.
    /// </summary>
    public FrameTransport()
    {
        sharedInfoSize = (uint)Marshal.SizeOf((Type)typeof(ControlChannelStruct));
        haveFrame = false;
        bitmapData = null;
        bitmapDataSize = 0;
        frameChannel1 = null;
        frameChannel2 = null;

        controlStruct = new ControlChannelStruct();
        controlStruct.bufferstates = 1;
        controlStruct.buffer1.bufid = -1;
        controlStruct.buffer2.bufid = -1;
        controlStruct.buffer1.clientpointer = 1;
        controlStruct.buffer2.clientpointer = 2;
        controlStruct.fourcccount = 0;
        controlStruct.buftype = BufferType.WINBUFFERS;

        controlChannel = new SharedMemoryChannel();
        bool success = controlChannel.CreateMapping(sharedInfoSize);

        if (!success)
        {
            throw new Exception("Unable to create memory mapping for video frame transport.");
        }

        controlChannel.OpenMapping(controlChannel.key);
        int error = Win32.GetLastError();

        if (error != 0)
        {
            throw new Exception("Unable to map memory for video frame transport.");
        }
    }
    #endregion


    #region Internal Members
    /// <summary>
    /// Send the control data.
    /// </summary>
    internal void SendControlData()
    {
        Marshal.StructureToPtr(controlStruct, controlChannel.data, false);
    }

    /// <summary>
    /// Get the control data.
    /// </summary>
    internal void GetControlData()
    {
        controlStruct.bufferstates = -1;
        controlStruct = (ControlChannelStruct)Marshal.PtrToStructure(controlChannel.data, typeof(ControlChannelStruct));
    }

    /// <summary>
    /// Communicate supported pixel formats to the runtime.
    /// </summary>
    /// <param name="count"></param>
    /// <param name="fourCcs"></param>
    internal void SetPreferences(int count, Int32[] fourCcs)
    {
        if (fourCcs.Length != 1)
        {
            throw new Exception("For now im assuming only one fourcc here.");
        }

        controlStruct.fourcccount = count;
        controlStruct.fourcc01 = fourCcs[0];
        controlStruct.fourcc02 = 0;
        controlStruct.fourcc03 = 0;
        controlStruct.fourcc04 = 0;
        controlStruct.fourcc05 = 0;
        controlStruct.fourcc06 = 0;
        controlStruct.fourcc07 = 0;
        controlStruct.fourcc08 = 0;
        controlStruct.fourcc09 = 0;
        controlStruct.fourcc10 = 0;

        SendControlData();
    }

    /// <summary>
    /// Get the buffer states.
    /// </summary>
    /// <returns></returns>
    internal int GetBufStates()
    {
        GetControlData();

        return controlStruct.bufferstates;
    }

    /// <summary>
    /// Return the channel's key.
    /// </summary>
    /// <returns></returns>
    internal uint Key()
    {
        return (uint)controlChannel.key;
    }

    /// <summary>
    /// Check if a new frame is available.
    /// </summary>
    /// <returns></returns>
    internal bool IsNewFrameAvailable()
    {
        GetControlData();
        int bufferState = (controlStruct.bufferstates & 0x3);

        if ((bufferState != 0x00) & (bufferState != 0x3))
        {
            return false;
        }

        return true;
    }

    /// <summary>
    /// Get the frame.
    /// </summary>
    /// <returns></returns>
    internal bool GetFrame()
    {
        int bufferState = (controlStruct.bufferstates & 0x03);

        if (!haveFrame & bufferState == 0x01) 
        { 
            return false; 
        }

        if (!haveFrame)
        {
            haveFrame = true;
        }

        if (bufferState == 0x00)
        {
            controlStruct.bufferstates |= 0x02;
        }

        if (bufferState == 0x03)
        {
            controlStruct.bufferstates &= ~0x02;
        }

        bufferState = (controlStruct.bufferstates & 0x03);

        FrameChannelStruct buffer;
        SharedMemoryChannel channel;

        if (bufferState == 0x1)
        {
            buffer = controlStruct.buffer1;
            channel = frameChannel1;
        }
        else if (bufferState == 0x2)
        {
            buffer = controlStruct.buffer2;
            channel = frameChannel2;
        }
        else
        {
            throw new Exception("Error: unexpected video control buffer state.");
        }

        if (channel == null)
        {
            channel = new SharedMemoryChannel();
            bool success = channel.OpenMapping(buffer.bufid);

            if (!success)
            {
                throw new Exception("Unable to map frame bitmap channel.");
            }
        };

        if (channel != null)
        {
            if (channel.key != buffer.bufid)
            {
                return false;
            };
        };

        width = buffer.width;
        height = buffer.height;
        int bytesPerPixel = buffer.bitsperpixel >> 3;
        int newFrameSize = width * height * bytesPerPixel;

        if (newFrameSize != bitmapDataSize)
        {
            bitmapData = null;
            bitmapDataSize = newFrameSize;
            bitmapData = new byte[bitmapDataSize];
        }

        Marshal.Copy(channel.data, bitmapData, 0, bitmapDataSize);

        if (bufferState == 0x1)
        {
            controlStruct.buffer1 = buffer;
            frameChannel1 = channel;
        }
        else if (bufferState == 0x2)
        {
            controlStruct.buffer2 = buffer;
            frameChannel2 = channel;
        }

        SendControlData();

        return true;
    }
    #endregion
}

結構內部的BufferType必須是一個枚舉,因為保存枚舉值的自定義Type是缺陷。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM