C# 如何在从C到C的结构中获取非托管变长C数组?

C# 如何在从C到C的结构中获取非托管变长C数组?,c#,pinvoke,marshalling,unmanaged,managed,C#,Pinvoke,Marshalling,Unmanaged,Managed,如何返回MIB\u IPFORWARDROW数组 struct MIB_IPFORWARDTABLE { public uint Size; [MarshalAs(/* what goes here? */)] public IPFORWARDROW[] Table; }; [DllImport("iphlpapi", CharSet = CharSet.Auto)] private static extern int GetIpForwardTable( I

如何返回
MIB\u 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
    */
}
(见附件)

我看到了:


但无论我做什么,fwdTable.Table总是null,IntPtr.Zero或0。当然,如果没有引发异常..

此线程似乎正是您要寻找的:

他们的解决方案使用蛮力循环将原始数组复制到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);
    }
[ComVisible(false),StructLayout(LayoutKind.Sequential)]
内部结构IPForwardTable
{
公共单位面积;
[Marshallas(UnmanagedType.ByValArray,SizeConst=1)]
公共IPROW[]表;
};
[ComVisible(false)、StructLayout(LayoutKind.Sequential)]
内部结构IPFORWARDROW
{
内部int/*DWORD*/dwForwardDest;
内部int/*DWORD*/dwForwardMask;
内部int/*DWORD*/dwForwardPolicy;
内部int/*DWORD*/dwForwardNextHop;
内部int/*DWORD*/dwforwardiIndex;
内部int/*DWORD*/dwForwardType;
内部int/*DWORD*/dwForwardProto;
内部int/*DWORD*/dwForwardAge;
内部int/*DWORD*/dwForwardNextHopAS;
内部int/*DWORD*/dwForwardMetric1;
内部int/*DWORD*/dwForwardMetric2;
内部int/*DWORD*/dwForwardMetric3;
内部int/*DWORD*/dwForwardMetric4;
内部int/*DWORD*/dwForwardMetric5;
};
[DllImport(“iphlapi”,CharSet=CharSet.Auto)]
私有外部静态int GetIpForwardTable(IntPtr/*PMIB_IPFORWARDTABLE*/pipfrowardtable,ref int/*PULONG*/pdwSize,bool bOrder);
[DllImport(“iphlapi”,CharSet=CharSet.Auto)]
私有外部静态int CreateIpForwardEntry(IntPtr/*PMIB_IPFORWARDROW*/pRoute);
静态void Main(字符串[]参数)
{
变量fwdTable=IntPtr.Zero;
int size=0;
var结果=GetIpForwardTable(fwdTable,ref size,true);
fwdTable=Marshal.AllocHGlobal(大小);
结果=GetIpForwardTable(fwdTable,ref size,true);
var str=(IPForwardTable)Marshal.PtrToStructure(fwdTable,typeof(IPForwardTable));
IPFORWARDROW[]表=新IPFORWARDROW[str.Size];
IntPtr p=fwdTable+Marshal.SizeOf(str.Size);
对于(int i=0;i
检查一下:@MichaelKniffen-我看不出它是如何关联的
var str=(IPForwardTable)Marshal.PtrToStructure(fwdTable,typeof(IPForwardTable))抛出
NullReferenceException
oops。清理代码后,我删除了几个重要的代码(比如分配存储结果所需的内存)。编辑。