構造体をポインターに設定しようとすると、非常に奇妙なエラーが表示されます...無効なキャスト例外がスローされ、その理由について完全に混乱しています。この関数は、オブジェクト、IntPtr、ブール値フラグの 3 つのパラメーターを要求します。私が設定しているものはすべて...そしてそれらを明示的にキャストしても違いはありません。オブジェクトは構造体で、Intptr はポインターでデータを持ち、フラグは単に false に設定されています。
以前にこのようなシナリオでこの無効なキャスト例外を受け取った人はいますか?
編集
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
}