2013-02-18 48 views
2

我有下面的C++结构如何转换Lparam型在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; 

并转换成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; 
     }; 

我用下面的两种方法来将Lparam型转换的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)); 

但是,它不会成功,也不发出常规错误信息,而不是我得到的消息,在输出窗口“型‘System.TypeLoadException’发生在mscorlib.dll中的第一次机会异常”。 有人能告诉我我的转换有什么问题吗?

+1

对于初学者来说,你的字符集是ascii,而不是unicode。对值数组也使用'fixed'关键字。 – leppie 2013-02-18 07:21:23

+0

@leppie我不明白使用固定的关键字值数组。你能更具体还是举个例子? – icewall 2013-02-18 08:52:19

+0

请参阅http://msdn.microsoft.com/en-us/library/zycewsya(v=vs.80).aspx – leppie 2013-02-18 08:57:24

回答

0

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

第二个问题是LOGININFO的最后一个字段。它被定义为

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

但在你的非托管代码,它是

ACCOUNTINFO accountlist [999]; 

SizeConst参数应改为999

+0

我尝试了您提供的所有解决方案,但不起作用像之前一样。还有其他建议吗? – icewall 2013-02-18 08:51:02