HoloLens Callbacks with Native Library
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.
Answer by blainebell · Jun 27, 2017 at 06:38 PM
did you ever get this working? Can you debug native plugins from within the Emulator?
Your answer