我正在从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;
}
我的问题是我无法在IEnumerable中将数据(是AnotherStruct的数组)投射到object []。所以我无法访问数据[I]并且没有数据。长度
有什么想法吗?
答案 0 :(得分:1)
通常,我建议使用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;
}
当编组将其传递给非托管代码时,编组器应该为您做正确的事情。
答案 1 :(得分:0)
您可以像这样获得数组的长度:
if (data is Array a)
Console.WriteLine(a.Length);
c#中的数组始终从Array
派生,因此可以将其强制转换为该数组。
但是如果可能的话,我建议使用Damien's answer