2012-07-06 47 views
0

嘗試將結構設置爲指針時出現非常奇怪的錯誤...無效的轉換異常被拋出,我對此感到困惑。該函數要求3個參數,一個對象,IntPtr和一個布爾標誌。我所設定的所有這些......甚至明確地將它們鑄造成這樣也沒有區別。該對象是一個結構,Intptr是一個指針並且有數據,並且該標誌僅被設置爲false。Marshal.StructureToPtr InvalidCastException

有沒有人在這種情況下收到這個invalidcastexception?

EDIT

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 
} 
+1

你能告訴我們一些代碼嗎? – Marco 2012-07-06 15:16:26

+0

'StructureToPtr'函數本身不應該引發該異常。最可能的原因是您傳遞給它的參數表達式中存在錯誤。你可以請張貼調用代碼嗎? – JaredPar 2012-07-06 15:22:12

+0

添加了類...發生在SendControlData函數中。 – bl4kh4k 2012-07-06 15:23:00

回答

1

BufferType結構內部必須是一個枚舉,作爲自定義類型保持枚舉值是缺陷。