我在DLL中有一个C ++函数,它接受一个指向结构的指针,JPInfo,在函数中填充了从服务器接收的数据,C ++结构的布局如下所示:
typedef struct JP
{
unsigned char type;
DWORD value;
} JP;
typedef struct JPInfo
{
JP jps[3];
_int16 ConT;
_int16 CallT;
unsigned char ret;
unsigned char count;
unsigned char JPOffset;
unsigned char JPPeriod;
} JPInfo;
该函数在DLL中导出,如下所示:
__declspec(dllexport) DWORD __stdcall GetJPInfo(JPInfo* jpi, DWORD time);
该函数接受一个指向JPInfo结构的指针,我试图在C#中模拟这个结构
[StructLayout(LayoutKind.Sequential, Size = 5), Serializable]
public struct JP
{
byte type;
int value;
}
[StructLayout(LayoutKind.Sequential,Size=23),Serializable]
public struct JPInfo
{
JP[] jps;
Int16 ConT;
Int16 CallT;
byte ret;
byte count;
byte JPOffset;
byte JPPeriod;
}
我尝试从C#中调用函数,如下所示:
[DllImport("DLLImp.dll")]
unsafe public static extern int GetJP(ref JPInfo jpi, int time);
// then in main...
JPInfo jpi = new JPInfo;
GetJackpotValues(ref jpi, 4000);
我收到类型为“System.ExecutionEngineException”的未处理异常。我的JPInfo结构中没有固定大小的JP结构数组,所以我不知道如何处理它。
感谢。
答案 0 :(得分:4)
您是否尝试删除结构上的“大小”属性?在做类似的事情时,我没有必须指定尺寸。对于您的数组属性,请尝试将它们归为:
[StructLayout(LayoutKind.Sequential)]
public struct JPInfo
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
JP[] jps;
Int16 ConT;
Int16 CallT;
byte ret;
byte count;
byte JPOffset;
byte JPPeriod;
}
答案 1 :(得分:2)
假设C ++结构已打包,您的C#结构应如下所示:
[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct JP
{
byte type;
uint value;
}
[StructLayout(LayoutKind.Sequential, Pack=1)]
public struct JPInfo
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst=3)]
JP[] jps;
Int16 ConT;
Int16 CallT;
byte ret;
byte count;
byte JPOffset;
byte JPPeriod;
}
另一方面,如果它们未打包,则将Pack
参数移除到StructLayout
属性。您应该在C ++头文件中查找#pragma pack
语句,以了解C ++结构是否已打包。
我猜测C ++结构是打包的,因为你说它们被映射到从服务器接收的数据。
您的导入应该是这样的:
[DllImport("DLLImp.dll")]
public static extern uint GetJP(ref JPInfo jpi, uint time);
DWORD
转换为uint
而不是int
,此处不需要不安全的代码。