如何在c#中将LParam转换为Struct

本文关键字:转换 Struct LParam 中将 | 更新日期: 2023-09-27 17:59:45

我有以下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的首次机会异常"。有人能告诉我我的皈依有什么问题吗?

如何在c#中将LParam转换为Struct

代码的第一个明显问题在于CharSet.Unicode。非托管代码中结构的字段都定义为char,这是一个单字节字符。您应该对所有结构使用CharSet.Ansi

第二个问题出现在LOGININFO的最后一个字段中。它被定义为

[MarshalAs(UnmanagedType.Struct, SizeConst = 99)]
public ACCOUNTINFO[] accountlist;

但在非托管代码中,它是

ACCOUNTINFO accountlist [999];

SizeConst参数应更改为999