我从C#代码调用C库。我调用的函数将包含struct数组的struct作为参数:
struct Example1Struct
{
char* a;
uint16_t b;
AnotherStruct* c;
}
c这是一个指向AnotherStruct的指针数组。
我的C#代码中的结构看起来像这样
public struct Example1Struct
{
public IntPtr StationName;//is char*
public UInt16 IdCode;
public IntPtr AnotherStruct; //array of struct AnotherStruct
}
public static IntPtr MarshalToPointer(object data)
{
Type valueType = data.GetType();
IntPtr buf = IntPtr.Zero;
if (valueType.IsArray)
{
if (data is char[])
{
var d = data as char[];
buf = Marshal.AllocHGlobal(Marshal.SizeOf(d.GetType().GetElementType()) * d.Length);
}
else if (data is char[,])
{
var d = data as char[,];
buf = Marshal.AllocHGlobal(Marshal.SizeOf(d.GetType().GetElementType()) * d.Length);
}
else
{
buf = Marshal.AllocHGlobal(Marshal.SizeOf(data.GetType().GetElementType()) * count);
long LongPtr = buf.ToInt64(); // Must work both on x86 and x64
for (int I = 0; I < data.Lenght; I++)
{
IntPtr RectPtr = new IntPtr(LongPtr);
Marshal.StructureToPtr(data[I], RectPtr, false); // You do not need to erase struct in this case
LongPtr += Marshal.SizeOf(typeof(Rect));
}
}
return buf;
}
else
buf = Marshal.AllocHGlobal(Marshal.SizeOf(data));
Marshal.StructureToPtr(data, buf, false);
return buf;
}
我的问题在于我无法将数据(谁是Another Struct的数组)转换为object [],也不能在IEnumerable中。所以我无法访问数据[I]并且没有data.Length
任何的想法 ?
通常我建议使用MarshalAs
属性而不是编写手动编组代码。看起来像:
public struct Example1Struct
{
public IntPtr StationName;//is char*
public UInt16 IdCode;
public IntPtr AnotherStruct; //array of struct AnotherStruct
}
可能:
public struct Example1Struct
{
[MarshalAs(UnmanagedType.LPStr)]
public string StationName;
public UInt16 IdCode;
[MarshalAs(UnmanagedType.LPArray)]
public AnotherStruct[] OtherStructs;
}
当你将它传递给非托管代码时,编组器应该为你做正确的事情。
您可以像这样获取数组的长度:
if (data is Array a)
Console.WriteLine(a.Length);
c#中的数组总是来自Array
,因此您可以将其转换为该数组。
但如果可能在您的真实代码中,我建议使用Damien's answer