Search code examples
c#type-conversionpinvokeip-addressintptr

C# - Converting IntPtr pointing to sockaddr structure to IPAddress


From a P/Invoked native function, I get an IntPtr which points to a sockaddr structure. How can I convert it to an IPAddress?

Thanks!


Solution

  • Since you can't directly Marshal a sockaddr type into an IPAddress type, you'd have to make a managed struct out of it first to marshal it into:

    [StructLayout(LayoutKind.Sequential)]
    internal struct sockaddr_in
    {
        internal EnumLib.ADDRESS_FAMILIES sin_family;
        internal ushort sin_port;
        internal in_addr sin_addr;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] internal byte[] sin_zero;
    
        internal static sockaddr_in FromString(string host, int port)
        {
        var sockaddr = new sockaddr_in();
        var lpAddressLength = Marshal.SizeOf(sockaddr);
        WSAStringToAddress(host + ":" + port, EnumLib.ADDRESS_FAMILIES.AF_INET, IntPtr.Zero,
                          ref sockaddr, ref lpAddressLength);
        return sockaddr;
        }
    }
    

    You could then use Marshal.PtrToStructure to obtain a sockaddr_in type from your IntPtr like so:

    (sockaddr_in) Marshal.PtrToStructure(address, typeof(sockaddr_in));

    After that it should be fairly simple to create a new IPAddress object from the data you've just retrieved.

    You can find the ADDRESS_FAMILIES enum that is contained in EnumLib in the above example here: http://pastie.org/8103489

    There are originally more members of the struct over at pinvoke.net, just take a look here if you are interested in them but I reckon you won't need them at all in this specific situation.