尝试将结构设置为指针时出现非常奇怪的错误......抛出了无效的强制转换异常,我完全不知道为什么。该函数要求提供 3 个参数、一个对象、IntPtr 和一个布尔标志。我正在设置的所有这些......甚至明确地将它们转换为这样没有区别。对象是一个结构,Intptr 是一个指针并且有数据,标志只是设置为假。
以前有没有人在这种情况下收到过这个 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
}