Упорядочивание массива структур С# — FatalExecutionEngineError

Эта функция в Oculus SDK выдает код ошибки 0xc0000005:

[DllImport(LibFile)]
private static extern void ovrHmd_GetRenderScaleAndOffset(ovrFovPort fov,
                                                          ovrSizei textureSize,
                                                          ovrRecti renderViewport,
                                                          [MarshalAs(UnmanagedType.LPArray, SizeConst = 2)]
                                                          [Out] out ovrVector2f[] uvScaleOffsetOut);

Никакие другие функции PInvoke не выдают ошибки, но я думаю, что эта отличается, потому что вывод представляет собой массив. На самом деле есть еще одна функция, которая возвращает массив и выдает ту же ошибку:

[DllImport(LibFile)]
private static extern void ovrHmd_GetEyeTimewarpMatrices(IntPtr hmd, ovrEyeType eye, ovrPosef renderPose,
                                                         [MarshalAs(UnmanagedType.LPArray, SizeConst = 2)]
                                                         [Out] out ovrMatrix4f_Raw[] twnOut);

Вот объявления структур:

[StructLayout(LayoutKind.Sequential)]
public struct ovrVector2f
{
    public float x, y;
}

[StructLayout(LayoutKind.Sequential)]
public struct ovrMatrix4f_Raw
{
    public float m00;
    public float m01;
    public float m02;
    public float m03;

    public float m10;
    public float m11;
    public float m12;
    public float m13;

    public float m20;
    public float m21;
    public float m22;
    public float m23;

    public float m30;
    public float m31;
    public float m32;
    public float m33;
}

Глядя на исходный код SDK, я знаю, что по крайней мере ovrHmd_GetRenderScaleAndOffset выглядит довольно скучно, я не могу представить, что ошибка может возникнуть внутри SDK.

Я чувствую, что мне нужно указать размеры где-то в сигнатуре функции? И мне интересно, ограничено ли это выходными параметрами или любыми параметрами «массива структуры».


person etodd    schedule 05.09.2014    source источник
comment
4.5.2 имеет поддержку Simd и векторных классов для поддержки.   -  person Jay    schedule 05.09.2014
comment
Да, это очень редко заканчивается хорошим концом. Вы говорите маршаллеру pinvoke скопировать собственный массив и уничтожить его. Последние неизменно бомбят. Единственная надежда, что у вас есть неправильное объявление, используйте простые ovrVector2f[] uvScaleOffsetOut, без атрибутов out. И передать достаточно большой массив.   -  person Hans Passant    schedule 05.09.2014


Ответы (1)


Параметры массива объявлены неправильно. Использование out вводит ложный дополнительный уровень косвенности. Вам нужно передать массив, который вы выделяете, и позволить неуправляемому коду заполнить его. Объявите параметр следующим образом

private static extern void ovrHmd_GetRenderScaleAndOffset(
    ovrFovPort fov,                                       
    ovrSizei textureSize,
    ovrRecti renderViewport,
    [Out] ovrVector2f[] uvScaleOffsetOut
);

Выделите массив перед вызовом функции:

ovrVector2f[] uvScaleOffsetOut = new ovrVector2f[2];

FWIW, это помогло бы, если бы вы показали неуправляемую сторону интерфейса.

person David Heffernan    schedule 05.09.2014