简体   繁体   English

将 struct 数组元组化为 Ptr

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM