我有以下c ++结构
typedef struct {
char szAccountNo[11];
char szAccountName[40];
char act_pdt_cdz3[3];
char amn_tab_cdz4[4];
char expr_datez8[8];
char granted;
char filler[189];
}ACCOUNTINFO;
typedef struct {
char szDate [14];
char szServerName [15];
char szUserID [8];
char szAccountCount [3];
ACCOUNTINFO accountlist [999];
}LOGININFO;
typedef struct{
int TrIndex;
LOGININFO *pLoginInfo;
}LOGINBLOCK;
并转换为C#类
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public class ACCOUNTINFO
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)]
public string szAccountNo;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 40)]
public string szAccountName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 3)]
public string act_pdt_cdz3;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 4)]
public string amn_tab_cdz4;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
public string expr_datez8;
public char granted;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 189)]
public string filler;
};
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public class LOGININFO
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
public string szDate;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 15)]
public string szServerName;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
public string szUserID;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 3)]
public string szAccountCount;
[MarshalAs(UnmanagedType.Struct, SizeConst = 99)]
public ACCOUNTINFO[] accountlist;
};
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public class LOGINBLOCK
{
[MarshalAs(UnmanagedType.I4)]
public int TrIndex;
[MarshalAs(UnmanagedType.Struct, SizeConst = 1)]
public LOGININFO pLoginInfo;
};
我使用以下两种方法在WndProc中转换LParam。
1. TrStruct.LOGINBLOCK lb = new TrStruct.LOGINBLOCK();
lb = (TrStruct.LOGINBLOCK)m.GetLParam(typeof(TrStruct.LOGINBLOCK));
2. TrStruct.LOGINBLOCK lb = (TrStruct.LOGINBLOCK) Marshal.PtrToStructure(m.LParam, typeof(TrStruct.LOGINBLOCK));
但是,它不会成功,也不会发出常规错误消息,而是在“输出”窗口中收到消息“mscorlib.dll中出现类型'System.TypeLoadException'的第一次机会异常”。 谁能告诉我转换有什么问题?
答案 0 :(得分:0)
代码的第一个明显问题在于CharSet.Unicode
。非托管代码中的结构字段都定义为char
,这是一个单字节字符。您应该对所有结构使用CharSet.Ansi
。
第二个问题出现在LOGININFO
的最后一个字段中。它被定义为
[MarshalAs(UnmanagedType.Struct, SizeConst = 99)]
public ACCOUNTINFO[] accountlist;
但是在你的非托管代码中,它是
ACCOUNTINFO accountlist [999];
SizeConst
参数应更改为999
。