Как вернуть массив 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)
Я видел это: Как мне организовать структуру, содержащую массив с переменным размером, на С#?
Но независимо от того, что я делаю, 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
В их решении используется цикл грубой силы, чтобы скопировать исходный массив в System.Array IPFORWARDROW.
Окончательный код будет выглядеть примерно так:
[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));
NullReferenceException