1

How do I return the MIB_IPFORWARDROW array?

struct MIB_IPFORWARDTABLE
{
    public uint Size;

    [MarshalAs(/* what goes here? */)]
    public IPFORWARDROW[] Table;
};

[DllImport("iphlpapi", CharSet = CharSet.Auto)]
private static extern int GetIpForwardTable(
    IntPtr /* MIB_IPFORWARDTABLE* */ pIpForwardTable,
    ref uint /* ULONG* */ pdwSize,
    bool bOrder);

public static MIB_IPFORWARDROW[] Temp()
{
    var fwdTable = IntPtr.Zero;
    uint size = 0;
    var result = GetIpForwardTable(fwdTable, ref size, true);
    fwdTable = Marshal.AllocHGlobal((int) size);
    result = GetIpForwardTable(fwdTable, ref size, true);

    /*
    what now ?
    I tried:

    var table = (MIB_IPFORWARDTABLE) Marshal.PtrToStructure(fwdTable, typeof(MIB_IPFORWARDTABLE));

    but table.Table is always null
    */
}

(See GetIpForwardTable)

I've seen this: How do I marshal a struct that contains a variable-sized array to C#?

But whatever I do, fwdTable.Table is always null, IntPtr.Zero or 0. That is ofcourse, if no Exception is thrown..

2

1 Answer 1

1

This thread seems to be exactly what you are looking for: http://social.msdn.microsoft.com/Forums/vstudio/en-US/19a3ce21-e395-4151-86f6-723a64272f0d/calling-getipforwardtable-from-c?forum=csharpgeneral

Their solution employs a brute force loop to copy the raw array into a System.Array of IPFORWARDROW.

The final code would look something like this:

    [ComVisible(false), StructLayout(LayoutKind.Sequential)]
    internal struct IPForwardTable
    {
        public uint Size;

        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
        public IPFORWARDROW[] Table;
    };

    [ComVisible(false), StructLayout(LayoutKind.Sequential)]
    internal struct IPFORWARDROW
    {
        internal int /*DWORD*/ dwForwardDest;
        internal int /*DWORD*/ dwForwardMask;
        internal int /*DWORD*/ dwForwardPolicy;
        internal int /*DWORD*/ dwForwardNextHop;
        internal int /*DWORD*/ dwForwardIfIndex;
        internal int /*DWORD*/ dwForwardType;
        internal int /*DWORD*/ dwForwardProto;
        internal int /*DWORD*/ dwForwardAge;
        internal int /*DWORD*/ dwForwardNextHopAS;
        internal int /*DWORD*/ dwForwardMetric1;
        internal int /*DWORD*/ dwForwardMetric2;
        internal int /*DWORD*/ dwForwardMetric3;
        internal int /*DWORD*/ dwForwardMetric4;
        internal int /*DWORD*/ dwForwardMetric5;
    };

    [DllImport("iphlpapi", CharSet = CharSet.Auto)]
    private extern static int GetIpForwardTable(IntPtr /*PMIB_IPFORWARDTABLE*/ pIpForwardTable, ref int /*PULONG*/ pdwSize, bool bOrder);

    [DllImport("iphlpapi", CharSet = CharSet.Auto)]
    private extern static int CreateIpForwardEntry(IntPtr /*PMIB_IPFORWARDROW*/ pRoute);

    static void Main(string[] args)
    {
        var fwdTable = IntPtr.Zero;
        int size = 0;

        var result = GetIpForwardTable(fwdTable, ref size, true);
        fwdTable = Marshal.AllocHGlobal(size);

        result = GetIpForwardTable(fwdTable, ref size, true);
        var str = (IPForwardTable)Marshal.PtrToStructure(fwdTable, typeof(IPForwardTable));

        IPFORWARDROW[] table = new IPFORWARDROW[str.Size];
        IntPtr p = fwdTable + Marshal.SizeOf(str.Size);
        for (int i = 0; i < str.Size; ++i)
        {
            table[i] = (IPFORWARDROW)Marshal.PtrToStructure(p, typeof(IPFORWARDROW));
            p += Marshal.SizeOf(typeof(IPFORWARDROW));
        }


        Marshal.FreeHGlobal(fwdTable);
    }
Sign up to request clarification or add additional context in comments.

2 Comments

var str = (IPForwardTable)Marshal.PtrToStructure(fwdTable, typeof(IPForwardTable)); throws NullReferenceException
oops. Cleaning up the code, I deleted a couple of important ones (like allocating the memory needed to store the result). Edited.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.