C# Marshal.StructureToPtr InvalidCastException
尝试将结构设置为指针时出现非常奇怪的错误。。。抛出了无效的强制转换异常,我完全搞不懂为什么。该函数要求3个参数,一个对象、IntPtr和一个布尔标志。我正在设置的所有内容。。。甚至明确地将它们作为这样的角色也没有什么区别。对象是一个结构,Intptr是一个指针并有数据,而标志仅仅设置为false 以前有人在这种情况下收到过这种无效的例外吗 编辑C# Marshal.StructureToPtr InvalidCastException,c#,C#,尝试将结构设置为指针时出现非常奇怪的错误。。。抛出了无效的强制转换异常,我完全搞不懂为什么。该函数要求3个参数,一个对象、IntPtr和一个布尔标志。我正在设置的所有内容。。。甚至明确地将它们作为这样的角色也没有什么区别。对象是一个结构,Intptr是一个指针并有数据,而标志仅仅设置为false 以前有人在这种情况下收到过这种无效的例外吗 编辑 internal class FrameTransport { #region Fields internal SharedMemory
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
}
内部类FrameTransport
{
#区域字段
内部共享内存通道控制通道;
内部控制通道结构控制结构;
内部SharedMemoryChannel框架通道1;
内部SharedMemoryChannel框架通道2;
内部字节[]位映射数据;
内部int位图数据大小;
内部单元共享大小;
内框;
内部内部高度;
内部整数宽度;
#端区
#区域结构
[StructLayout(LayoutKind.Sequential,Pack=1)]
内部结构FrameChannelStruct
{
公共Int32 bufid;
公共Int32大小;
公共Int32宽度;
公众Int32高度;
公共Int32位像素;
公共互联网中心;
公众导向;
公共Int64客户端指针;
};
[StructLayout(LayoutKind.Sequential,Pack=1)]
内部结构控制通道结构
{
美国的公共财政;
公共FrameChannelStruct buffer1;
公共FrameChannelStruct buffer2;
公共缓冲区类型buftype;
公共Int32配置;
公共Int32 fourcccount;
公共Int32 fourcc01;
公共Int32 fourcc02;
公共Int32 fourcc03;
公共Int32 fourcc04;
公共Int32 fourcc05;
公共Int32 fourcc06;
公共Int32 fourcc07;
公共Int32 fourcc08;
公共Int32 fourcc09;
公共Int32 fourcc10;
};
#端区
#区域构造函数
///
///构造器。
///
公共交通(
{
sharedInfoSize=(uint)Marshal.SizeOf((Type)typeof(ControlChannelStruct));
haveFrame=false;
bitmapData=null;
bitmapDataSize=0;
frameChannel1=null;
frameChannel2=null;
controlStruct=新的ControlChannelStruct();
controlStruct.BufferState=1;
controlStruct.buffer1.bufid=-1;
controlStruct.buffer2.bufid=-1;
controlStruct.buffer1.clientpointer=1;
controlStruct.buffer2.clientpointer=2;
controlStruct.Fourccount=0;
controlStruct.buftype=BufferType.WINBUFFERS;
controlChannel=新的SharedMemoryChannel();
bool success=controlChannel.CreateMapping(sharedInfoSize);
如果(!成功)
{
抛出新异常(“无法为视频帧传输创建内存映射”);
}
controlChannel.OpenMapping(controlChannel.key);
int error=Win32.GetLastError();
如果(错误!=0)
{
抛出新异常(“无法映射视频帧传输的内存”);
}
}
#端区
#区域内部成员
///
///发送控制数据。
///
内部无效SendControlData()
{
Marshal.StructureToPtr(controlStruct,controlChannel.data,false);
}
///
///获取控制数据。
///
内部无效GetControlData()
{
controlStruct.BufferState=-1;
controlStruct=(ControlChannelStruct)Marshal.PtrToStructure(controlChannel.data,typeof(ControlChannelStruct));
}
///
///将支持的像素格式传送到运行时。
///
///
///
内部void SetPreferences(int count,Int32[]fourCcs)
{
如果(四立方厘米长度!=1)
{
抛出新的异常(“现在我假设这里只有一个fourcc。”);
}
controlStruct.fourcccount=计数;
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();
}
///
///获取缓冲区状态。
///
///
内部int GetBufStates()
{
GetControlData();
返回controlStruct.bufferstates;
}
///
///返回频道的键。
///
///
内部uint键()
{
返回(uint)controlChannel.key;
}
///
///检查是否有新的框架可用。
///
///
内部bool IsNewFrameAvailable()
{
GetControlData();
int bufferState=(controlStruct.bufferstates&0x3);
如果((bufferState!=0x00)和(bufferState!=0x3))
{
返回false;
}
返回true;
}
///
///拿着镜框。
///
///
内部bool GetFrame()
{
int bufferState=(controlStruct.bufferstates&0x03);
如果(!haveFrame&bufferState==0x01)
{
返回false;
}
如果(!haveFrame)
{
haveFrame=true;
}
如果(bufferState==0x00)
{
controlStruct.BufferState |=0x02;
}
如果(bufferState==0x03)
{
controlStruct.BufferState&=~0x02;
}
bufferState=(controlStruct.bufferstates&0x03);
帧通道结构缓冲区;
SharedMemoryChannel频道;
如果(bufferState==0x1)
{
buffer=controlStruct.buffer1;
通道=帧通道1;
}
else if(bufferState==0x2)
{
buffer=controlStruct.buffer2;
通道=帧