2009-08-24 13 views
0

我正在嘗試使用P/Invoke與本機DLL進行交互,但它需要一個in_addr結構參數。我一直看到它的許多不同類型的定義,但哪個最好用?在C中使用in_addr#

另外,如何將C#IPAddress對象轉換爲in_addr結構?

回答

2

請嘗試以下

[StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] 
public struct in_addr { 

    /// Anonymous1 
    public Anonymous1 S_un; 
} 

[StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Explicit)] 
public struct Anonymous1 { 

    /// Anonymous2 
    [System.Runtime.InteropServices.FieldOffsetAttribute(0)] 
    public Anonymous2 S_un_b; 

    /// Anonymous3 
    [System.Runtime.InteropServices.FieldOffsetAttribute(0)] 
    public Anonymous3 S_un_w; 

    /// u_long->unsigned int 
    [System.Runtime.InteropServices.FieldOffsetAttribute(0)] 
    public uint S_addr; 
} 

[StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] 
public struct Anonymous2 { 

    /// u_char->unsigned char 
    public byte s_b1; 

    /// u_char->unsigned char 
    public byte s_b2; 

    /// u_char->unsigned char 
    public byte s_b3; 

    /// u_char->unsigned char 
    public byte s_b4; 
} 

[StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)] 
public struct Anonymous3 { 

    /// u_short->unsigned short 
    public ushort s_w1; 

    /// u_short->unsigned short 
    public ushort s_w2; 
} 

PInvoke Interop Assistant

編輯盪滌匿名名生成。

+0

有什麼辦法可以將其轉換爲IPAddress對象並將其轉換爲IPAddress對象嗎? – 2009-08-24 18:17:19

+0

@David,沒有內置函數,但編碼不應太糟糕。 – JaredPar 2009-08-24 18:23:47

+0

我沒有太多的C經驗,所以讓我知道如果我有這個權利。我使用BitConverter將IPAddress的字節轉換爲Int32,然後將其分配給S_addr(將其轉換爲uint)。 Anonymous2中的4字節字段(s_b1-s_b4)被分配來自IPAddress'字節數組的前4個字節。這會工作嗎?我應該如何處理s_w1和s_w2? – 2009-08-24 18:41:12

4

如果有人有興趣,這裏是完整的代碼。它能夠將一個IPAddress對象解壓到一個in_addr結構並再次返回。

[StructLayout(LayoutKind.Sequential)] 
public struct in_addr { 
    public Anonymous1 S_un; 

    [StructLayoutAttribute(LayoutKind.Explicit)] 
    public struct Anonymous1 { 
     [FieldOffsetAttribute(0)] 
     public Anonymous2 S_un_b; 

     [FieldOffsetAttribute(0)] 
     public Anonymous3 S_un_w; 

     [FieldOffsetAttribute(0)] 
     public uint S_addr; 
    } 

    [StructLayoutAttribute(LayoutKind.Sequential)] 
    public struct Anonymous2 { 
     public byte s_b1; 
     public byte s_b2; 
     public byte s_b3; 
     public byte s_b4; 
    } 

    [StructLayoutAttribute(LayoutKind.Sequential)] 
    public struct Anonymous3 { 
     public ushort s_w1; 
     public ushort s_w2; 
    } 

    public in_addr(IPAddress address) : this(address.GetAddressBytes()) { } 

    public in_addr(byte[] address) { 
     // Set this first, otherwise it wipes out the other fields 
     S_un.S_un_w = new Anonymous3(); 

     S_un.S_addr = (uint)BitConverter.ToInt32(address, 0); 

     S_un.S_un_b.s_b1 = address[0]; 
     S_un.S_un_b.s_b2 = address[1]; 
     S_un.S_un_b.s_b3 = address[2]; 
     S_un.S_un_b.s_b4 = address[3]; 
    } 

    /// <summary> 
    /// Unpacks an in_addr struct to an IPAddress object 
    /// </summary> 
    /// <returns></returns> 
    public IPAddress ToIPAddress() { 
     byte[] bytes = new[] { 
      S_un.S_un_b.s_b1, 
      S_un.S_un_b.s_b2, 
      S_un.S_un_b.s_b3, 
      S_un.S_un_b.s_b4 
     }; 

     return new IPAddress(bytes); 
    } 

} 

像JaredPar,我還是不知道該怎麼做Anonymous3,但它其實並不重要,因爲它不能直接設定。由於它們都具有相同的FieldOffset,因此設置一個字段會清除所有其他字段。它似乎工作,但是,我並不太擔心它。