将指向C#struct的指针发送到C ++ DLL中

时间:2012-03-01 14:10:38

标签: c# c++ dll pinvoke

我在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结构数组,所以我不知道如何处理它。

感谢。

2 个答案:

答案 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,此处不需要不安全的代码。