Обратные вызовы HoloLens с собственной библиотекой

Моя цель - вызвать методы, которые реализованы в Unity Code, из моей библиотеки UWP. (Так что я могу использовать их в своем проекте HoloLens)

Я попробовал это с большим проектом, но потерпел неудачу. Поэтому я написал простой пример, чтобы упростить поиск ошибки и исключить другие влияния. Но все равно я получаю ту же ошибку.

Моя рабочая среда:

  • 64-битный компьютер с ОС Windows 10
  • Micsrosoft Visual Studio Community 2015 версия 14.0.25431.01 обновление 3
  • HoloLens Emulator 10.0.14393.0
  • Unity 5.5.0f3 Personal (64 бит)

Создание UWP DLL:

Чтобы приблизиться к этому, я создал C++ DLL(Windows Universal) в Visual Studio 2015 следующим образом:

Новый проект> Visual C++ > Windows > Universal > DLL(Universal Windows)

После того, как проект был сгенерирован автоматически, я добавил свой код. Итак, код выглядит так:

Код родной библиотеки:

SimpleProjectDLL.cpp:

#include "pch.h"
#define DLL_EXPORT __declspec(dllexport)

typedef void(*CB_V)();
typedef void(*CB_V_VI)(const char * a, int b);

CB_V_VI cb_native_log;
CB_V cb_call;

void log()
{
    // this method makes problems !
    cb_native_log("Call for callback", 1);
}

extern "C" {
    DLL_EXPORT void initInterfaceCallbacks(
        CB_V_VI native_log,
        CB_V call
    ) {
        cb_native_log = native_log;
        cb_call = call;
    }

    DLL_EXPORT void callSmth() 
    {
        cb_call();
    }

    DLL_EXPORT int getSomeInt()
    {
        return 42;
    }

    DLL_EXPORT void initCallback() 
    {
        log();
    }
}

SimpleProjectDLL.h готовит делегатов:

SimpleProjectDLL.h:

#pragma once
#include <cstdint>
#define DLL_EXPORT __declspec(dllexport)

extern "C" 
{
    typedef void(*CB_V)();
    typedef void(*CB_V_VI)(const char * a, int b);
}

Я не вносил никаких изменений в автоматически сгенерированные файлы dllmain.cpp, pch.cpp, pch.h или targetver.h.

Наконец я строю проект для режима "Release" и архитектуру "x86" для генерации DLL-файла. Расположение DLL-файла теперь: project-root-folder / Release / SimpleProject / SimpleProjectDLL.dll.

---------------------

Следующим шагом я создал новый проект Unity, добавил HoloLens-Toolkit и убедился, что новый проект работает нормально на эмуляторе.

Код проекта Unity:

После этого я добавил SimpleProjectDLL.dll в папку активов и внедрил следующий код:

Прежде всего нам нужно создать связь между делегатами. Cpp.cs готовит делегатов:

Cpp.cs

using UnityEngine;
using System;
using System.Runtime.InteropServices;

namespace Cpp
{
    delegate void DelegateV();
    delegate void DelegateVVi(IntPtr a, int b);
}

SimpleInterfaceCpp.cs инициализирует соединение:

SimpleInterfaceCpp.cs

using Cpp;
using System.Runtime.InteropServices;
using UnityEngine;

public static class SimpleInterfaceCpp
{
    public static void Init()
    {
         initInterfaceCallbacks(
            SimpleInterface.NativeLog,
            SimpleInterface.Call
        );
    }

    [DllImport(SimpleInterface.DLL)]
    private static extern void initInterfaceCallbacks(
        DelegateVVi native_log,
        DelegateV call
    );
}

Главный:

MainController.cs

using UnityEngine;
using System.Collections;
using System.Runtime.InteropServices;

public class MainController : MonoBehaviour 
{
    void Start ()
    {
        SimpleInterfaceCpp.Init();
        SimpleInterface.TestCalls();
    }
}

SimpleInterface.cs вызывает методы:

SimpleInterface.cs

using System;
using UnityEngine;
using System.Runtime.InteropServices;
using AOT;
using IntPtr = System.IntPtr;
using Cpp;

using StringReturn = System.IntPtr;

public class SimpleInterface
{
    public const string DLL = "SimpleProjectDLL";

    public static void TestCalls()
    {
        // This works fine
        int number = getSomeInt();
        Debug.Log("getSomeInt: " + number);

        // This also works fine and outputs "--- A callback ---"
        callSmth();

        // This call gives the output "call_log: native log" but crashes afterwards !
        initCallback();

    }

    [MonoPInvokeCallback(typeof(DelegateVVi))]
    public static void NativeLog(IntPtr logMessage,
         int logLevel)
    {
        string result = StringFromCReturn(logMessage);
        UnityEngine.Debug.Log(result); // outputs "call_log: native log"
    }

    [MonoPInvokeCallback(typeof(DelegateV))]
    public static void Call()
    {
        UnityEngine.Debug.Log("--- A callback---");
    }

    [DllImport(DLL)]
    private static extern void initCallback();
    [DllImport(DLL)]
    private static extern void callSmth();
    [DllImport(DLL)]
    private static extern int getSomeInt();

    public static string StringFromCReturn(StringReturn someReturnVal)
    {
        return Marshal.PtrToStringAnsi(someReturnVal);
    }
}

Теперь, если я создаю SLN, открываю проект в Visual Studio и запускаю его с "Эмулятором HoloLens", я получаю следующий вывод:

getSomeInt: 42

(Filename: C:/buildslave/unity/build/artifacts/generated/Metro/runtime/DebugBindings.gen.cpp Line: 51)


--- A callback---

(Filename: C:/buildslave/unity/build/artifacts/generated/Metro/runtime/DebugBindings.gen.cpp Line: 51)


call_log: native log

(Filename: C:/buildslave/unity/build/artifacts/generated/Metro/runtime/DebugBindings.gen.cpp Line: 51)


The program '[1932] SimpleProject.exe' has exited with code -1073740791 (0xc0000409).

После этого приложение просто закрывается.

Итак, мой вопрос: кто-нибудь знает, в чем может быть проблема?

Это правильный способ использовать обратные вызовы в проекте HoloLens?

Или кто-то знает, как найти описание ошибки для кода "-1073740791 (0xc0000409)"?


Дополнительная информация: Я также попробовал это на реальном устройстве HoloLens, та же проблема, так что проблема не лежит в эмуляторе.

0 ответов

Ошибка STATUS_STACK_BUFFER_OVERRUN. Вызов уничтожил стек вызовов.

У вас есть разные объявления обратных вызовов в SimpleProjectDLL.cpp и SimpleProjectDLL.h. В Cpp-файле используется диалог вызовов "CPP", в заголовке используется диалог вызовов "C".

Вы должны изменить SimpleProjectDLL.cpp, удалив

typedef void(*CB_V)();
typedef void(*CB_V_VI)(const char * a, int b);

и добавление

#include "SimpleProjectDLL.h"
Другие вопросы по тегам