C# 封送结构同时保留它;非托管;

C# 封送结构同时保留它;非托管;,c#,c,pinvoke,C#,C,Pinvoke,我正在对一个DLL进行p调用,该DLL返回一个void**结构指针列表,所有指针都是相同类型的,为了强制转换并从该列表中删除我的结构,需要将该结构视为非托管结构。我试图封送的结构的主要元凶是C端的以下两个字段: char name[1024]; int crop[4]; 大多数指南建议在托管端的相应结构上使用string或int[],但拥有这些字段会使其成为托管结构,因此无法从void**列表中提取 还有什么方法可以封送这些字段以获得非托管结构?您可以使用关键字在数据结构中创建具有固定大小数组

我正在对一个DLL进行p调用,该DLL返回一个void**结构指针列表,所有指针都是相同类型的,为了强制转换并从该列表中删除我的结构,需要将该结构视为非托管结构。我试图封送的结构的主要元凶是C端的以下两个字段:

char name[1024];
int crop[4];
大多数指南建议在托管端的相应结构上使用string或int[],但拥有这些字段会使其成为托管结构,因此无法从void**列表中提取

还有什么方法可以封送这些字段以获得非托管结构?

您可以使用关键字在数据结构中创建具有固定大小数组的缓冲区:

unsafe struct Foo
{
    public fixed byte name[1024];
    public fixed int crop[4];
}

static unsafe void DumpCrops(void** ptr, int count)
{
    Foo** p = (Foo**)ptr;

    for (int i = 0; i < count; i++)
    {
        Foo* f = p[i];

        for (int j = 0; j < 4; j++)
        {
            Console.WriteLine(f->crop[j]);
        }
    }
}
不安全结构Foo
{
公共固定字节名[1024];
公共固定国际作物[4];
}
静态不安全无效转储(无效**ptr,整数计数)
{
Foo**p=(Foo**)ptr;
for(int i=0;icrop[j]);
}
}
}

您需要在结构上的该点添加一行,如图所示

[StructLayout(LayoutKind.Sequential, Pack = 1)] public unsafe struct _FOOBAR { [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 1024, ArraySubType = System.Runtime.InteropServices.UnmanagedType.I2)] char name[1024]; [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray, SizeConst = 4, ArraySubType = System.Runtime.InteropServices.UnmanagedType.I4)] int crop[4]; }; [StructLayout(LayoutKind.Sequential,Pack=1)] 公共不安全结构\u FOOBAR{ [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray,SizeConst=1024,ArraySubType=System.Runtime.InteropServices.UnmanagedType.I2)] 字符名[1024]; [System.Runtime.InteropServices.MarshalAsAttribute(System.Runtime.InteropServices.UnmanagedType.ByValArray,SizeConst=4,ArraySubType=System.Runtime.InteropServices.UnmanagedType.I4)] int-crop[4]; }; 您需要仔细检查属性位UnmanagedType中的最后一位

希望有帮助, 顺致敬意,
Tom。

如果您这样声明,结构将在不需要帮助或不安全关键字的情况下封送:

using System.Runtime.InteropServices;
...
  [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
  public struct Example {
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024)]
    public string name;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
    int[] crop;
  }

将void*转换为具有Marshal.PtrToStructure()的结构。

这对于使结构更加友好非常有用,尽管我仍然需要不安全的代码来访问列表中的所有结构。这应该不是必需的,如果它是void**,它应该由Marshal.ReadIntPtr()覆盖。您的帖子中没有足够的细节来说明列表是如何实现的,链表还是指针数组。