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