Hololens2开发笔记-VS2019创建DLL项目供Unity调用

前言

上一篇尝试将 Hololens2 的研究模式与 Unity 项目进行了整合。归根结底,就是将研究模式的相关 API(C++)构建成 DLL 文件,才能实现在 Unity(C#)中进行调用。这篇就介绍一下如何自己创建一个最简单的 DLL 文件,实现在 Unity 中的调用。

环境

  • Windows 10 教育版 18363.1379
  • Unity 2019.4.20f1c1
  • VS2019 16.8.6
  • WIN SDK 10.0.18362.0
  • Hololens2 内部预览版本 10.0.20301.1000

VS2019创建DLL项目

选择创建新项目,搜索 DLL 模板,选择 DLL(通用Windows) 模板,点击下一步

图片可能因为网络原因掉线了,请刷新或直接点我查看图片~

设置项目名称和位置,点击创建

图片可能因为网络原因掉线了,请刷新或直接点我查看图片~

选择目标版本最低版本,一般默认即可。实际上,项目创建完成后,在项目属性设置中也可更改这个设置,如何更改可以看:Hololens2-运行研究模式官方案例(SensorVisualization)

图片可能因为网络原因掉线了,请刷新或直接点我查看图片~

编写DLL代码

主要更改的就是 HL2RmUnityPlugin.hHL2RmUnityPlugin.cpp 这两个文件。编写代码如下

HL2RmUnityPlugin.h

#pragma once

#define FUNCTIONS_EXPORTS_API extern "C" __declspec(dllexport)

extern "C" {
	typedef struct IMUInputForUnity {
		double x;
		double y;
		double z;
	}INPUT;

	typedef struct IMUOutputForUnity {
		double x;
		double y;
		double z;
	}OUTPUT;
}

namespace HL2Stream {

	FUNCTIONS_EXPORTS_API int __stdcall GetIMUStreaming(INPUT* input, OUTPUT* output);

}

HL2RmUnityPlugin.cpp

#include "pch.h"
#include "HL2RmUnityPlugin.h"

int __stdcall HL2Stream::GetIMUStreaming(INPUT* input, OUTPUT* output)
{
	output->x = input->x * input->x;
	output->y = input->y * input->y;
	output->z = input->z * input->z;
	return 200;
}

GetIMUStreaming 函数接收两个结构体作为参数,返回 int 类型表示执行结果。

生成DLL文件

因为最终 Unity 项目要部署到 Hololens2 上,所以这里构建方式选择 Release ARM64。点击菜单栏生成 -> 生成解决方案。成功后即可在项目目录下找到 ARM64\Release\HL2RmUnityPlugin\HL2RmUnityPlugin.dll 文件了。

Unity调用DLL

把 dll 文件拷贝到 Unity 项目的 Assets\Plugins\HL2RmStream 目录下,目录不存在就创建。然后在 Assets\Scripts 目录下创建一个 C# 脚本,编写如下:

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

public class GetTime : MonoBehaviour
{
    [StructLayout(LayoutKind.Sequential)]
    struct INPUT
    {
        public double x;
        public double y;
        public double z;
    };

    [StructLayout(LayoutKind.Sequential)]
    struct OUTPUT
    {
        public double x;
        public double y;
        public double z;
    }

#if ENABLE_WINMD_SUPPORT
    [DllImport("HL2RmUnityPlugin", EntryPoint = "GetIMUStreaming", CallingConvention = CallingConvention.StdCall)]
    public static extern int GetIMUStreaming(IntPtr pv1, IntPtr pv2);
#endif

    public TextMeshPro textMeshPro;

    private void Start()
    {
#if ENABLE_WINMD_SUPPORT
        INPUT pIn = new INPUT();
        pIn.x = 1.0;
        pIn.y = 2.0;
        pIn.z = 3.0;

        int sizeIn = Marshal.SizeOf(typeof(INPUT));
        IntPtr pBuffIn = Marshal.AllocHGlobal(sizeIn);
        Marshal.StructureToPtr(pIn, pBuffIn, true);

        int sizeOut = Marshal.SizeOf(typeof(OUTPUT));
        IntPtr pBuffOut = Marshal.AllocHGlobal(sizeOut);

        int result = GetIMUStreaming(pBuffIn, pBuffOut);

        OUTPUT pOut = (OUTPUT)Marshal.PtrToStructure(pBuffOut, typeof(OUTPUT));

        textMeshPro.text = $"{pOut.x} {pOut.y} {pOut.z}";
#endif
    }
}

C# 需要将结构体转为指针进行调用。为了能看到运行结果,创建一个 TextMeshPro 对象挂载到这个脚本时来显示运行结果。

部署到Hololens上

因为 Windows 机器不能运行 ARM64 的程序,所以只能把 Unity 项目构建部署到 Hololens 上运行即可~

部署相关操作看之前的文章吧,这里不在赘述了。接下来来好好的捣鼓捣鼓 Hololens 的研究模式吧~

参考

Unity3D中调用C++动态链接库(dll)-两种方式(Managed Plugins 和 Native Plugins)

如果这篇文章对您有帮助,欢迎给我的 github项目 点一个⭐ ο(=•ω<=)ρ⌒☆

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
Unity开发Hololens 2应用程序中,实现空间锚点的创建、保存和重新读取需要按照以下步骤进行: 1. 创建空间锚点:在Unity创建一个新的游戏对象,然后将SpatialAnchor组件添加到该对象上。在Hololens 2中移动设备时,可以使用MRTK中的SpatialMappingObserver组件来捕获周围环境的空间数据。当需要创建空间锚点时,将SpatialAnchor组件附加到需要锚定的游戏对象上,然后调用SpatialAnchorManager类的CreateAnchor方法来创建空间锚点。 ```csharp SpatialAnchor spatialAnchor = gameObject.AddComponent<SpatialAnchor>(); SpatialAnchorManager.Instance.CreateAnchor(spatialAnchor); ``` 2. 保存空间锚点:在Hololens 2设备上,使用SpatialAnchorExporter类将空间锚点保存到本地文件中。在Unity中,可以使用SpatialAnchorManager类的TryExportAnchor方法将空间锚点导出到指定文件路径。 ```csharp string filePath = "SpatialAnchor.txt"; SpatialAnchorManager.Instance.TryExportAnchor(spatialAnchor, filePath); ``` 3. 重新读取空间锚点:在Hololens 2设备上,使用SpatialAnchorImporter类从本地文件中读取保存的空间锚点。在Unity中,可以使用SpatialAnchorManager类的TryImportAnchor方法从指定文件路径读取空间锚点。 ```csharp string filePath = "SpatialAnchor.txt"; SpatialAnchor spatialAnchor = gameObject.AddComponent<SpatialAnchor>(); SpatialAnchorManager.Instance.TryImportAnchor(spatialAnchor, filePath); ``` 值得注意的是,导出和导入空间锚点的过程需要耗费一定时间,因此在进行这些操作时需要考虑异步处理,以免阻止主线程的执行。可以使用C#中的异步编程技术,如async/await关键字或协程来处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Apple_Coco

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值