如何在从C到C#的结构中获得非托管可变长度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.这是当然,如​​果没有抛出Exception ..

这个主题似乎正是你想要的: http : //social.msdn.microsoft.com/Forums/vstudio/en-US/19a3ce21-e395-4151-86f6-723a64272f0d/calling-getipforwardtable-from-c?论坛= csharpgeneral

他们的解决方案采用powershell循环将原始数组复制到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); }