将结构的非托管数组编组为托管数组

时间:2020-01-08 20:44:32

标签: c# c++ interop

我想干净有效地将自定义的色点结构从C ++应用程序传输到C#应用程序中。

在引擎盖下,自定义结构由浮点数组成。因此,在此之前,我将事情分解成一个浮点数数组,然后在执行Marshal.Copy之后重新构建结构,但这不是很干净或很难维护。我希望能够执行类似的批量复制,但同时填写C#数组的元素。我通过将c ++数组序列化为具有已知点数的字节缓冲区并将其传递来开始了这条路径,但是该方法的大量复制部分使我难以理解。下面的代码可以工作,但是需要在每个内存地址处调用Marshal.PtrToStructure,这太慢了。

C#代码

    protected override void TransferPoints( IntPtr points, int count )
    {
        PointXYZRGB[] colorPoints = new PointXYZRGB[ count ];

        for( int i = 0; i < count; i++)
        {
            // Works but is too slow
            colorPoints[i] = (PointXYZRGB) System.Runtime.InteropServices.Marshal.PtrToStructure(points + (32 * i), typeof(PointXYZRGB));
        }
    }

有色点

    [StructLayout(LayoutKind.Sequential, Pack=16)]
    public struct PointXYZRGB 
    {
        public Vector3Data Position;

        public Color3Data Color;
    }

Vector3Data和Color3Data都是仅由三个浮点数组成的结构

    [Serializable]
    public struct Vector3Data
    {
        public float x;
        public float y;
        public float z;
    }
    [Serializable]
    public struct Color3Data
    {
        public float r;
        public float g;
        public float b;
    }

C ++函数模板如下

void TransferPoints( uint8_t* buffer, int32_t counts );

当我尝试执行此类操作以一次复制所有内容时,我没有得到任何值。

        protected override void TransferPoints( IntPtr points, int count )
        {
            PointXYZRGB[] colorPoints = new PointXYZRGB[ count ];

            System.Runtime.InteropServices.Marshal.PtrToStructure(points, colorPoints);
        }

如果有任何建议,我将不胜感激!

修改 更多上下文:我的C#代码订阅了点列表,并通过TransferPoints委托

public class ManagedPointWrapper
{
    [DllImport("example.so")]
    public static extern IntPtr newPointXYZRGBSubscriber( IntPtr transferPoints );
}

创建订户

ManagedPointWrapper.newPointXYZRGBSubscriber(System.Runtime.InteropServices.Marshal.GetFunctionPointerForDelegate( transferXYZRGBPointsCallback ) );

代表看起来像这样:

    /// Delegate declaration for the callback to be passed into the c++ interop layer
    /// </summary>
    [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
    public delegate void TransferXYZRGBPointsDelegate(IntPtr xyzrgb, Int32 count);

0 个答案:

没有答案
相关问题