如何在从 C 到 C# 的结构中获取非托管可变长度 C 数组?
Posted
技术标签:
【中文标题】如何在从 C 到 C# 的结构中获取非托管可变长度 C 数组?【英文标题】:How to get unmanaged variable-length C-array within a struct from C to C#? 【发布时间】:2014-05-22 14:14:49 【问题描述】:如何返回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)
我看过这个: How do I marshal a struct that contains a variable-sized array to C#?
但无论我做什么,fwdTable.Table 始终为 null,IntPtr.Zero 或 0。当然,如果没有抛出异常..
【问题讨论】:
检查这个:***.com/questions/162897/marshal-char-in-c-sharp @MichaelKniffen - 我不明白它是如何相关的 【参考方案1】:这个帖子似乎正是您要找的:http://social.msdn.microsoft.com/Forums/vstudio/en-US/19a3ce21-e395-4151-86f6-723a64272f0d/calling-getipforwardtable-from-c?forum=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);
【讨论】:
var str = (IPForwardTable)Marshal.PtrToStructure(fwdTable, typeof(IPForwardTable));
throws NullReferenceException
哎呀。清理代码,我删除了几个重要的(比如分配存储结果所需的内存)。已编辑。以上是关于如何在从 C 到 C# 的结构中获取非托管可变长度 C 数组?的主要内容,如果未能解决你的问题,请参考以下文章