Использование in_addr в C # - PullRequest
       44

Использование in_addr в C #

0 голосов
/ 24 августа 2009

Я пытаюсь взаимодействовать с нативной DLL с помощью P / Invoke, но для этого требуется параметр in_addr struct. Я продолжаю видеть много разных видов определений для него, но какой лучше использовать?

Кроме того, как я могу преобразовать объект C # IPAddress в in_addr структуру?

Ответы [ 2 ]

5 голосов
/ 25 августа 2009

Если кому-то интересно, вот полный код. Он способен распаковать объект 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, установка одного поля очищает все остальные. Похоже, это работает, поэтому я не слишком беспокоюсь об этом.

2 голосов
/ 24 августа 2009

Попробуйте следующее

[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

РЕДАКТИРОВАТЬ Очистить анонимные имена.

...