Маршал неуправляемый массив структур в управляемый массив - PullRequest
1 голос
/ 08 января 2020

Я хотел бы аккуратно и эффективно передать пользовательскую структуру цветных точек из моего приложения 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 1028 *

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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...