我正在调用一个DLL,它返回一个结构指针的void **列表,它们都是相同的类型。 From what I've read,为了从我的结构中强制转换结构,结构需要被视为不受管理。我试图编组的结构的主要元凶是C方面的以下两个字段:
char name[1024];
int crop[4];
大多数指南建议在托管端的相应结构上使用string或int [],但是具有这些字段的那些使得它成为托管结构,因此无法从void **列表中提取。
我可以用另一种方式编组这些字段,这些字段为我提供了一个非托管结构吗?
答案 0 :(得分:1)
您可以使用fixed关键字在数据结构中创建具有固定大小数组的缓冲区:
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]);
}
}
}
答案 1 :(得分:1)
如果您声明如下所示,结构将在没有帮助或需要unsafe关键字的情况下编组:
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;
}
使用Marshal.PtrToStructure()将void *转换为结构。
答案 2 :(得分:0)
你需要在结构上的那一点添加一行,如图所示......
[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]; };
您需要仔细检查属性位中的最后一位,UnmanagedType ...
希望有所帮助, 最好的祝福, 汤姆。