1、最近做項目遇到,C#調用C++dll里的函數需要傳遞結構體參數,發現這個并不是簡單的在C#里定義相應的結構體就可以的,下面以一個例子來說明解決的辦法,C++中的函數和結構體如下:
uint msec_set_igr_gen_cfg(int port, IGR_GEN_T *igr_gen)
{
return 0;
}
typedef struct {
? int aa_disable; /*/< authentiation adjust checking disable */
? int badtag_rej; /*/< reject packet if it is bypassed due to badtag */
? int pad_en; /*/< pad non-rejected packets up to 64B */
? int byp_ctl_sl; /*/< bypass packet if SL field does not correspond to packet len */
? int byp_ctl_v; /*/< bypass packet if V bit is set */
? int byp_ctl_sc; /*/< bypass packet if SC bit and either ES or SCB bits are set */
? int byp_ctl_ec; /*/< bypass packet if DC bits are not 00 or 11 */
? int sectag_flag; /*/< select which flag bit indicates that a SEC tag was present in pkt */
} IGR_GEN_T;
在C#中 首先需要使用Dllimport將相應的C++dll load進來,然后定義相應的結構體,具體如下:
? ? ? ? [DllImport("..\\debug\\mgd_MacSec.dll")]
? ? ? ? private static extern UInt32 msec_set_igr_gen_cfg(int port, IntPtr igr_gen);
??
? ? ? ? 結構體定義:
? ? [StructLayout(LayoutKind.Sequential)]
? ? ?public class IGR_GEN_T?
? ? ?{
? ? ? ? ?int aa_disable; /*/< authentiation adjust checking disable */
? ? ? ? ?int badtag_rej; /*/< reject packet if it is bypassed due to badtag */
? ? ? ? ?int pad_en; /*/< pad non-rejected packets up to 64B */
? ? ? ? ?int byp_ctl_sl; /*/< bypass packet if SL field does not correspond to packet len */
? ? ? ? ?int byp_ctl_v; /*/< bypass packet if V bit is set */
? ? ? ? ?int byp_ctl_sc; /*/< bypass packet if SC bit and either ES or SCB bits are set */
? ? ? ? ?int byp_ctl_ec; /*/< bypass packet if DC bits are not 00 or 11 */
? ? ? ? ?int sectag_flag; /*/< select which flag bit indicates that a SEC tag was present in pkt */
? ? ? ? ?public IGR_GEN_T()
? ? ? ? ?{
? ? ? ? ? ? ?aa_disable = 0;
? ? ? ? ? ? ?badtag_rej = 0;
? ? ? ? ? ? ?pad_en = 0;
? ? ? ? ? ? ?byp_ctl_ec = 0;
? ? ? ? ? ? ?byp_ctl_sc = 0;
? ? ? ? ? ? ?byp_ctl_sl = 0;
? ? ? ? ? ? ?byp_ctl_v = 0;
? ? ? ? ? ? ?sectag_flag = 0;
? ? ? ? ?}
? ? ?} ;
? 在代碼中具體引用函數時如下所示,
? ? ?IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(igr_gen));
? ? ? ? ? ? ?Marshal.StructureToPtr(igr_gen, ptr, false);
? ? ? ? ? ? ?UInt32 ret = _msec_set_igr_gen_cfg(port, ptr);
? ? ? ? ? ? ?igr_gen = (IGR_GEN_T)Marshal.PtrToStructure(ptr, typeof(IGR_GEN_T));
? ? ? ? ? ? ?Marshal.FreeHGlobal(ptr);
? ? ? ? ? ? ?return ret;
從以上步驟可以看出,結構體參數的傳遞需要marshal做輔助做相應的轉化,以intptr的方式傳輸結構體參數。