c # к неуправляемому нарушению доступа к cll dll / "frame not in module" - PullRequest
0 голосов
/ 23 декабря 2018

У меня есть приложение на C # (в Unity3d mono), которое передает некоторые данные в неуправляемую DLL c ++ через C-API.Он передается во вложенном Struct, который включает в себя массив.Все хорошо, пока C-API не закрывается, когда (в } функции), когда я получаю сообщение «Frame not in Module» от VS2017, (если я «> Продолжить», я получу нарушение прав доступа 0xC0000005 который, как предполагает дизассемблирование, может пропустить ptr - так, вероятно, ошибка разыменования)

РЕДАКТИРОВАТЬ: Я думаю, это может быть из-за того, что моя исходная структура имеет указатель на массив // EDIT

чтовызывает это "Кадр не в модуле"?- оно не очень информативно как сообщение

и что я могу с этим поделать?

Мой код ...

У меня есть ac # иерархия структур.

private struct Vector3
{
    public float x;
    public float y;
    public float z;
}

private structure Location
{
    public Vector3 coords;
    public float distanceFromOrigin;
}

private struct Locations
{
    [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.Struct, SizeConst = 10)]
    public Location[] locations;
}

private struct Scene
{
    public Locations cam1;
    public Locations cam2;
    public float timeInMilliSecs;
}

Я создаю экземпляр Scene, и с cam1 и cam2 каждый получает массив 10 Locations.Все хорошо.На данный момент работает, как и ожидалось, и структура данных заполнена правильными данными.

Я передаю экземпляр Scene в неуправляемую DLL

[DllImport(dllname)]
private static extern void updateScene(Scene scene);

В моем c ++ Iиметь

extern "C" {
    DLL_EXPORT void updateScene(Scene scene);
}

и перегрузку

void updateScene(Scene scene) {
    setSecene(scene); // this calls function fine but with erroneous data
}

и подписи для эквивалентных структур

struct Vector3
{
    float x;
    float y;
    float z;
}

struct Location
{
    Vector3 coords;
    float distanceFromOrigin;
}

struct Locations
{
    Location locations[10];
}

struct Scene
{
    Locations cam1;
    Locations cam2;
    float timeInMilliSecs;
}

Структура Scene передается в C справильные данные отправляются на c ++.Но затем возникает проблема - я предполагаю, что это проблема с памятью, но я не уверен, что с этим делать.

Глядя на разборку, возможно, показывает, что это проблема с указателем?

0000000040BDAE57 49 89 0B mov qword ptr [r11],rcx

Может кто-нибудь помочь, пожалуйста?

Ответы [ 2 ]

0 голосов
/ 24 декабря 2018

В конце я упорядочил всю вложенную структуру в указателе - все изменения в c #

[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)]
private static extern void updateScene(IntPtr scene);

И затем, прежде чем вызвать updateScene (), я упорядочиваю структуру сцены

IntPtr  scenePtr = Marshal.AllocHGlobal(Marshal.SizeOf(scene));
Marshal.StructureToPtr(scene, scenePtr , true);
updateScene(scenePtr);

все остальное осталось прежним.

0 голосов
/ 24 декабря 2018

В последний раз вы говорите, что не меняете CallingConvention, поэтому измените значение на Cdecl.

Значение по умолчанию для DllImportAttribute равно WinApi, которое не очищает стек после функцииcall.

И значением по умолчанию для кода C является __cdecl, что также не очищает стек.Он ждет, пока вызывающая сторона очистит его.

Это исключение.

...