C#通过p/invoke调用C++ DLL的函数,需要传嵌套结构体数组的复杂参数,但是单步调试发现传入的数值却不正确,感觉是嵌套结构使用的问题,但是数据复杂,使用嵌套结构数组是最好的选择。代码如下:
小结构体:
[StructLayout(LayoutKind.Sequential)]
public struct UDTMinuteWayStat
{
public byte Flux;
public byte MaxSpeed;
public byte MinSpeed;
public ushort MinTimeHeadway;
public byte Speed;
public ushort TimeHeadway;
public ushort TimeOccupancy;
}
大结构体:
[StructLayout(LayoutKind.Sequential)]
public struct UDTMinuteStat
{
public byte Speed;
public ushort TimeOccupancy;
public ushort TotalFlux;
public ushort VTBigFlux;
public ushort VTMiddleFlux;
public ushort VTSmallFlux;
// [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]
public UDTMinuteWayStat[] Way;
}
调用时声明:
UDTMinuteStat[] udtCycleStatData = new UDTMinuteStat[5];
for(int i=0; i<5; i++)
{
udtCycleStatData[i].Way = new UDTMinuteWayStat[4];
}
//调用DLL函数
SPSendCurrentStatData( udtCycleStatData);
C++中代码如下:
typedef struct
{
TUint8 Flux;
TUint8 MaxSpeed;
TUint8 MinSpeed;
TUint16 MinTimeHeadway;
TUint8 Speed;
TUint16 TimeHeadway;
TUint16 TimeOccupancy;
}UDTMinuteWayStat;
typedef struct
{
TUint8 Speed;
TUint16 TimeOccupancy;
TUint16 TotalFlux;
TUint16 VTBigFlux;
TUint16 VTMiddleFlux;
TUint16 VTSmallFlux;
UDTMinuteWayStat Way[4];
} UDTMinuteStat;
函数定义为:
extern "C" void PASCAL EXPORT SPSendCurrentStatData(UDTMinuteStat udtCycleStatData)
感觉就是嵌套结构体的问题,调整C#中和C++中的结构体的顺序,使其保持一致,再调试看,大结构体内其他成员传值都正常,就是嵌套的小结构体数值不正常,加上[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 20)]或者[MarshalAs(UnmanagedType.AsAny)]都会报错,说“该类型无法作为结构类型封装处理”,是否和我在结构体应用时初始化WAY有关呢,实在是搞不懂了,在大结构体定义时初始化小结构体却初始化不了。
最终还是没搞定,msdn里的例子都看了,没有我这种嵌套结构体的应用例子,最后只好用笨办法解决问题,把嵌套的结构体拿出来单独做一个参数传,代码不优雅,但是好歹把功能实现了。