How to convert LParam to Struct in c#

1.4k Views Asked by At

I have the following c++ struct

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;

and converted into C# class

[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;
        };

I used the following two methods to convert the LParam within the WndProc.

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));

However, it doesn't get success nor emits an regular error message, instead I get the message "A first chance exception of type 'System.TypeLoadException' occurred in mscorlib.dll" in Output window. Could anyone tell me what's wrong with my conversion?

1

There are 1 best solutions below

1
On

The first apparent problem with your code lies in CharSet.Unicode. Fields of you structure in unmanaged code are all defined as char which is a single-byte character. You should use CharSet.Ansi for all your structures.

The second problem is in last field of LOGININFO. It is defined as

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

but in your unmanaged code, it is

ACCOUNTINFO accountlist [999];

The SizeConst parameter should be changed to 999.