簡體   English   中英

如何從C到C#的結構中獲取非托管的可變長度C數組?

[英]How to get unmanaged variable-length C-array within a struct from C to C#?

如何返回MIB_IPFORWARDROW數組?

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
    */
}

(請參閱GetIpForwardTable

我已經看到了: 如何編組包含C#可變大小數組的結構?

但是無論我做什么,fwdTable.Table始終為null,IntPtr.Zero或0。這當然是,如果沒有引發異常。

該線程似乎正是您所需要的: http : //social.msdn.microsoft.com/Forums/vstudio/en-US/19a3ce21-e395-4151-86f6-723a64272f0d/calling-getipforwardtable-from-c?論壇= csharpgeneral

他們的解決方案使用蠻力循環將原始數組復制到IPFORWARDROW的System.Array中。

最終代碼如下所示:

    [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);
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM