[英]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.