У меня есть матричный класс, который содержит массив с плавающей запятой фиксированного размера, который я хочу представить непосредственно в классе оболочки C #:
class Matrix
{
public:
float data[16];
...
};
Обычно при переносе этой структуры в C # я определяю упакованный типкак структура POD, которая будет использовать [StructLayout(LayoutKind.Sequential)]
и позволит мне напрямую маршалировать класс в и из C ++ / C #.Тем не менее, класс c ++ предоставляет другие типы (через члены или функции), которые не могут быть распределены таким образом, поэтому вместо этого мне придется использовать механизм PIMPL, где мой класс C # содержит непрозрачный указатель (IntPtr) на базовую структуру C ++.Однако я все же хотел бы напрямую предоставить базовый data
член структуры c ++ объекту C #.Под непосредственным пониманием я подразумеваю, что модификации элементов data
в C # будут напрямую отражаться в базовой структуре C ++ (т. Е. Член C # не может быть копией члена C ++).Моя идея состояла в том, чтобы выставить член data
в C # следующим образом:
public class Matrix
{
protected HandleRef cptr; // opaque reference to equivalent C++ instance
public float [] data
{
get
{
return Get_data(cptr);
}
}
[DllImport(MY_CPP_DLL, EntryPoint = "CSharp_Get_data", CharSet = CHARSET)]
[return: MarshalAs(UnmanagedType.LPArray, SizeConst = 16, ArraySubType = UnmanagedType.R4)]
private static extern float [] Get_Data(HandleRef in_object);
};
Где мой C ++ dll содержит функцию CSharp_Get_data
, которая выглядит следующим образом:
DLLEXPORT float * STDCALL CSharp_Get_data(Matrix *obj)
{
return obj->data;
}
Это компилируетсяхорошо как в C ++, так и в C #, но когда я пытаюсь сделать что-то подобное в c #:
Matrix asdf = new Matrix();
asdf.data[0] = 2.0f;
, я получаю исключение System.Runtime.InteropServices.MarshalDirectiveException, в котором указано Additional information: Cannot marshal 'return value': Invalid managed/unmanaged type combination.
IsЕсть ли способ, которым я могу использовать этот подход, но не столкнуться с этой ошибкой?Я знаю, что это довольно странный вариант использования, но мне кажется, что этот подход не нарушает ни один из стандартов сортировки, описанных MS здесь: https://docs.microsoft.com/en-us/dotnet/framework/interop/default-marshaling-for-arrays.
Спасибо за любую помощь.