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