Hello everyone.

The Mixed Reality Forums here are no longer being used or maintained.

There are a few other places we would like to direct you to for support, both from Microsoft and from the community.

The first way we want to connect with you is our mixed reality developer program, which you can sign up for at https://aka.ms/IWantMR.

For technical questions, please use Stack Overflow, and tag your questions using either hololens or windows-mixed-reality.

If you want to join in discussions, please do so in the HoloDevelopers Slack, which you can join by going to https://aka.ms/holodevelopers, or in our Microsoft Tech Communities forums at https://techcommunity.microsoft.com/t5/mixed-reality/ct-p/MicrosoftMixedReality.

And always feel free to hit us up on Twitter @MxdRealityDev.

HoloLens Callbacks with Native Library

alexfehalexfeh
edited January 2017 in Questions And Answers

My goal is to call methods, which are implemented in the Unity Code, from my UWP DLL. (So I can use them in my HoloLens Project)

I tried this with a bigger project but failed. Therefore I wrote a simple example to make it easier to find the mistake and exclude other influences.
But still, I get the same error.

My Working Environment:

  • 64-bit Computer with OS Windows 10
  • Micsrosoft Visual Studio Community
    2015 Version 14.0.25431.01 Update 3
  • HoloLens Emulator 10.0.14393.0
  • Unity 5.5.0f3 Personal (64 bit)

Creating the UWP DLL:

To approach this I created a C++ DLL(Windows Universal) in Visual Studio 2015 as followed:

New Project > Visual C++ > Windows > Universal > DLL(Universal Windows)

After the project was auto generated I added my code.
So the code looks like this:

Native Library Code:

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 is prepearing the delegates:

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);
}

I did not make any changes to the auto generated files dllmain.cpp, pch.cpp, pch.h or targetver.h.

Finally I build the project for "Release" mode and architecture "x86" to generate the DLL-file.
Location of the DLL-file is now: project-root-folder/Release/SimpleProject/SimpleProjectDLL.dll.

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

Next step I created a new Unity Project added the HoloLens-Toolkit and made sure that the new project is running fine on the emulator.

Unity Project Code:

After that I added the SimpleProjectDLL.dll in the Asset-Folder and implemented the following code:

First of all we need to create the connection between the delegates.
Cpp.cs prepears the Delegates:

Cpp.cs

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

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

SimpleInterfaceCpp.cs initializes the connection:

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
    );
}

Main:

MainController.cs

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

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

SimpleInterface.cs is calling the methodes:

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);
    }
}

Now if I create a SLN, open the project in Visual Studio and start it with the "HoloLens Emulator" I get the following Output:

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).

After that the App just closes.

So my Question is, does anyone know what the problem could be?

Is this the right way to use callbacks in a HoloLens Project?

Or does someone know how to find an error description for the code "-1073740791 (0xc0000409)" ?


Additional Information:
I also tried it on a real HoloLens device, same issue, so the problem does not lays at the emulator.

Tagged:

Answers

  • I have the same problem. My interface works on every other platform except HoloLens. Did you ever figure it out? I just submitted a bug to Unity

  • I also have this problem. Would love to hear from anyone who found a solution.

  • Did anyone resolve that issue? ihave the same?

Sign In or Register to comment.