[英]Marshal array of struct into Ptr
I am calling a C library from a C# code.我正在从 C# 代码调用 C 库。 The function I am calling take as parameter a struct containing arrays of struct :
我正在调用的函数将包含 struct 数组的结构作为参数:
struct Example1Struct
{
char* a;
uint16_t b;
AnotherStruct* c;
}
c here is an array of pointer to AnotherStruct. c 这里是一个指向 AnotherStruct 的指针数组。
the struct in my C# code look like this我的 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;
}
my problem here is that I cannot cast data (who is an array of AnotherStruct) to object[] , neither in IEnumerable.我的问题是我不能将数据(谁是另一个结构的数组)转换为 object[] ,在 IEnumerable 中也不能。 So I cannot access to data[I] and don't have data.Lenght
所以我无法访问 data[I] 并且没有 data.Lenght
Any idea ?任何的想法 ?
Usually I'd recommend using the MarshalAs
attribute rather than writing manual marshalling code.通常我会推荐使用
MarshalAs
属性而不是编写手动编组代码。 It looks like:看起来像:
public struct Example1Struct
{
public IntPtr StationName;//is char*
public UInt16 IdCode;
public IntPtr AnotherStruct; //array of struct AnotherStruct
}
Could be:可能:
public struct Example1Struct
{
[MarshalAs(UnmanagedType.LPStr)]
public string StationName;
public UInt16 IdCode;
[MarshalAs(UnmanagedType.LPArray)]
public AnotherStruct[] OtherStructs;
}
And the marshaller should do the right thing for you when you pass it to unmanaged code.当您将它传递给非托管代码时,编组器应该为您做正确的事情。
You can get the length of the array like this:您可以像这样获取数组的长度:
if (data is Array a)
Console.WriteLine(a.Length);
Arrays in c# always derive from Array
, so you can cast it to that. c# 中的数组总是派生自
Array
,因此您可以将其转换为该Array
。
But if possible in your real code, I'd recommend Damien's answer但如果可能的话,在你的真实代码中,我会推荐Damien 的答案
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.