我的 目标是调用方法 ,在 中实现团结 代码,来自 我的 UWP DLL . (所以我可以在我的 HoloLens 项目中使用它们)
我尝试了一个更大的项目,但失败了。因此我写了一个简单的例子,以便更容易发现错误并排除其他影响。
但是,我仍然遇到同样的错误。
我的工作环境:
2015 版本 14.0.25431.01 更新 3
创建 UWP DLL:
为了解决这个问题,我在 Visual Studio 2015 中创建了一个 C++ DLL(Windows 通用),如下所示:
新建项目 > Visual C++ > Windows > 通用 > DLL(通用 Windows)
项目自动生成后,我添加了我的代码。
所以代码看起来像这样:
native 库代码:
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 进行任何更改。
最后,我为“发布”模式和体系结构“x86”构建项目以生成 DLL 文件。
DLL 文件的位置现在是:项目根文件夹/发布/SimpleProject/SimpleProjectDLL.dll .
----------
下一步我创建了一个 新的 Unity 项目 添加了 HoloLens-Toolkit 并确保新项目在模拟器上运行良好。
Unity 项目代码:
之后我添加了 SimpleProjectDLL.dll 在 Asset-Folder 中并实现了以下代码:
首先,我们需要创建代表之间的连接。
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 Emulator”启动它,我会得到以下输出:
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 设备上尝试过,同样的问题,所以问题不在于模拟器。
最佳答案
错误是 STATUS_STACK_BUFFER_OVERRUN。该调用破坏了调用堆栈。
在 SimpleProjectDLL.cpp 和 SimpleProjectDLL.h 中有不同的回调声明。 cpp文件使用“CPP”调用 session ,header使用“C”调用 session 。
您应该通过删除来更改 SimpleProjectDLL.cpp
typedef void(*CB_V)();
typedef void(*CB_V_VI)(const char * a, int b);
并添加
#include "SimpleProjectDLL.h"
关于unity3d - 带有 native 库的 HoloLens 回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41853963/