我的目标是调用方法,它们在 Unity 代码中实现,来自 my UWP DLL 。 (所以我可以在我的HoloLens项目中使用它们)
我尝试了一个更大的项目,但失败了。因此,我写了一个简单的例子,以便更容易找到错误并排除其他影响。 但是,我仍然得到同样的错误。
我的工作环境:
创建UWP DLL:
为了解决这个问题,我在Visual Studio 2015中创建了一个C ++ DLL(Windows Universal),如下所示:
新项目> Visual C ++> Windows>通用> DLL(通用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进行任何更改。
最后,我为&#34;发布&#34;模式和架构&#34; x86&#34;生成DLL文件。 DLL文件的位置现在是: project-root-folder / Release / SimpleProject / SimpleProjectDLL.dll 。
---------------------
下一步我创建了一个新的Unity项目,添加了HoloLens-Toolkit,并确保新项目在模拟器上正常运行。
Unity项目代码:
之后我在Asset-Folder中添加了 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中打开该项目,然后使用&#34; HoloLens Emulator&#34;我得到以下输出:
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项目中使用回调的正确方法吗?
或者有人知道如何找到代码的错误描述&#34; -1073740791(0xc0000409)&#34; ?
其他信息: 我也尝试过一个真正的HoloLens设备,同样的问题,所以这个问题不会出现在模拟器上。
答案 0 :(得分: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"