我的工作环境:
- 64位电脑,安装了Windows 10操作系统 - Microsoft Visual Studio Community 2015版本14.0.25431.01 Update 3 - HoloLens模拟器10.0.14393.0 - Unity 5.5.0f3 Personal(64位)
创建UWP DLL:
为了实现这一点,我在Visual Studio 2015中创建了一个C++ DLL(Windows Universal),具体步骤如下:
新建项目 > Visual C++ > Windows > Universal > DLL(Universal Windows)
项目自动生成后,我添加了我的代码。所以代码看起来像这样:
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正在准备委托:
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设备上运行它,出现了同样的问题,因此问题不在模拟器上。