C#: APIs, Pointers and Marshaling

Chris Dent
Chris Dent used Ask the Experts™
on
Hopefully this is really easy for somebody, Friday afternoon is killing off my ability to research this properly :)

I have a C# project, it's trying to use dhcpsapi.dll, which is pretty well documented here:

http://msdn.microsoft.com/en-us/library/aa363376(VS.85).aspx

My code is below, I get the following error which doesn't seem interested in going away no matter how much I prod it.

Cannot marshal field 'Servers' of type 'Test.DHCP_SERVER_INFO_ARRAY': Generic types cannot be marshaled.

Which I'm pretty sure means I'm doing something fundamentally wrong when trying to get the "out" value (which is a pointer to an array of DHCP_SERVER_INFO).

Any help (including small prodding, as long as it's not too obscure for me the non-programmer :)) would be most appreciated!

Thanks,

Chris
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
 
namespace Test
{
    [StructLayout(LayoutKind.Sequential)]
    public struct DHCP_SERVER_INFO
    {
        // typedef struct _DHCPDS_SERVER {
        //    DWORD  Version;
        //    LPWSTR ServerName;
        //    DWORD  ServerAddress;
        //    DWORD  Flags;
        //    DWORD  State;
        //    LPWSTR DsLocation;
        //    DWORD  DsLocType;
        // }DHCPDS_SERVER, *PDHCPDS_SERVER, *LPDHCPDS_SERVER *PDHCPDS_SERVER, DHCP_SERVER_INFO, *PDHCP_SERVER_INFO, *LPDHCP_SERVER_INFO *PDHCP_SERVER_INFO;
 
        public int Version;
        public string ServerName;
        public uint IPAddress;
        public byte Flags;
        public int State;
        public string DsLocation;
        public int DsLocType;
    }
 
    [StructLayout(LayoutKind.Sequential)]
    public unsafe struct DHCP_SERVER_INFO_ARRAY
    {
        // typedef struct _DHCPDS_SERVERS {
        //    DWORD           Flags;
        //    DWORD           NumElements;
        //    LPDHCPDS_SERVER Servers;
        // }DHCPDS_SERVERS, *PDHCPDS_SERVERS, *LPDHCPDS_SERVERS *PDHCPDS_SERVERS, DHCP_SERVER_INFO_ARRAY, *PDHCP_SERVER_INFO_ARRAY, *LPDHCP_SERVER_INFO_ARRAY *PDHCP_SERVER_INFO_ARRAY;
 
        public int Flags;
        public int NumElements;
        [MarshalAs(UnmanagedType.LPArray)]
        public List<DHCP_SERVER_INFO> Servers;
    }
 
    class Program
    {
        [DllImport("dhcpsapi.dll")]
        public static extern unsafe uint DhcpEnumServers(
            int Flags,
            void* IdInfo,
            DHCP_SERVER_INFO_ARRAY DhcpServerInfoArray,
            void* CallbackFn,
            void* CallbackData
        );
 
        static unsafe void Main(string[] args)
        {
            DHCP_SERVER_INFO_ARRAY DhcpServerInfoArray = new DHCP_SERVER_INFO_ARRAY();
            Console.WriteLine(DhcpEnumServers(0, null, DhcpServerInfoArray, null, null));
        }
    }
}

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Commented:
If I am not totaly misstaken, this thread covers what you are looking for.
http://www.experts-exchange.com/Programming/Languages/C_Sharp/Q_21958297.html
 
Chris DentPowerShell Developer
Top Expert 2010

Author

Commented:
Hey MrHswede,

Thanks for that, I think you're right. The downside is it means learning (some) C++ as well. Ah well, it wouldn't be fun if it were easy.

Cheers!

Chris
Chris DentPowerShell Developer
Top Expert 2010

Author

Commented:
Thank you.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial