接入第三方SDK
前言
IdeaXR
不能直接调用外部第三方库的接口函数,需要经过一层中转的方式接入。
本教程主要介绍如何用 c++ 创建IVRNative
动态库 并且接入第三方库的内容。
编译IVRNative动态库
下文 使用 VS2019 编译动态dll 库文件。
编译前准备
- 你需要准备 开发C++ 的环境,本教程以 VS2019 为开发工具
- ivr 头文件和ivr静态库lib文件 点此下载
创建项目
使用 VS 2019 添加 动态链接库 项目:
点击创建后,如下所示:
添加 ivr头文件和lib静态库
将下载好的 ivr 文件和lib库 放入项目文件夹下:
配置 ivr头文件和lib静态库
选择项目 -> 鼠标右键 -> 属性,按照如下流程配置头文件和静态库:
静态库有2个文件 一个是debug 版本 ,另一个是release 版本,按自己所需选择对应库文件。
功能开发
创建头文件
首先,我们基于IVRNative
节点创建头文件, 我们将它命名为MyScriptClass.h
:
#include<IVR.hpp>
#include <Spatial.hpp>
namespace ivr {
class MyScriptClass : public Spatial
{
IVR_CLASS(MyScriptClass, Spatial)
private:
int some_data;
public:
static void _register_methods();
MyScriptClass();
~MyScriptClass();
void _init(); // 必须要有
void do_something(int index);//自定义方法
int get_some_data();//自定义方法
};
}
以上有一些注意事项,
IVR.hpp
,包含我们所有的基本定义。
Spatial.hpp
, 包含对 Spatial
类的绑定。我们将在我们的模块中继承这个类。
我们使用命名空间 ivr
, 因为IVRNative中的所有内容都在此命名空间中定义。
然后我们有了我们的类定义, 它通过继承3D节点 Spatial
(也可以继承其他节点)。 IVR_CLASS
宏 为我们设置了一些内部事物。
之后, 我们声明一个名为 some_data
的成员变量。
我们定义了我们的方法,包括构造函数和析构函数,但是还有其他两个函数可能看起来很熟悉。
第一个是我们的 _register_methods
, 这是一个静态函数, IdeaXR
内部将调用它来为我们找出 IVRNativeScript
上 可以调用哪些方法 以及 它暴露的属性。
第二个是我们的 _init
函数, 它是在 IdeaXR 中正确设置我们的对象之后调用的。 即使您没有在其中放置任何代码, 它也必须存在。
第三个是我们的 do_something
函数, 自定义的方法,名字自己命名
实现接口函数
接下来,我们创建 MyScriptClass.cpp
文件来实现我们的接口函数:
#include "pch.h"
#include "MyScriptClass.h"
#pragma comment(lib, "第三方SDK.lib")
using namespace ivr;
void MyScriptClass::_register_methods()
{
register_method("do_something", &MyScriptClass::do_something);
register_method("get_some_data", &MyScriptClass::get_some_data);
}
MyScriptClass::MyScriptClass()
{
}
MyScriptClass::~MyScriptClass()
{
// 添加需要清除的代码
}
void MyScriptClass::_init()
{
some_data = 1;
}
void MyScriptClass::do_something(int index)
{
// 可在此处调用第三方库的接口函数
}
int MyScriptClass::get_some_data()
{
// 可在此处调用第三方库的接口函数
return 0;
}
上述代码应该很清晰, 我们正在实现我们在头文件中定义的每个类的方法。
注意 register_method
调用 必须是 public
修饰的方法, 否则在 IVRScript
脚本 中将无法使用它。不需要在 IVRScript
脚本中调用的方法无需绑定注册,如上的_init
方法。
导出接口类
还有一个我们需要的 C++ 文件;
我们将它命名为 MyPlugin.cpp
。 我们现在需要的是一小段代码, 告诉 IdeaXR
我们的 IVRNative
插件中的所有 IVRNativeScripts。
#include "pch.h"
#include "IVR.hpp"
#include "MyScriptClass.h"
extern "C" void IVR_EXPORT ivr_native_init(ivr_native_init_options * o) {
ivr::IVR::native_init(o);
}
extern "C" void IVR_EXPORT ivr_native_terminate(ivr_native_terminate_options * o) {
ivr::IVR::native_terminate(o);
}
extern "C" void IVR_EXPORT ivr_nativescript_init(void* handle) {
ivr::IVR::nativescript_init(handle);
ivr::register_class<ivr::MyScriptClass>();
}
请注意, 我们这里没有使用 ivr
命名空间, 因为这里实现的三个函数需要在没有命名空间的情况下定义。
当 IdeaXR
加载我们的插件并卸载它时, 分别调用 ivr_native_init
和 ivr_native_terminate
函数。
我们在这里所做的只是解析我们的绑定模块中的函数来初始化它们, 但你可能需要根据需求来设置更多内容。
重要的功能是第三个函数叫做 ivr_nativescript_init
,我们为动态库中的每个类调用函数 register_class
来注册该类。
编译完成
经过上述步骤,已经可以编译动态库文件了。使用 VS2019 编译后会生成MyScript.dll
。
如果编译出错,请注意,需要把 pch.h
中的 framework.h
移动到dllmain.cpp
中。
到此,编译已完成。
创建一个IVRNative插件
在IdeaXR中创建插件
经过上述教程后,相信你已经上手了。现在开始创建插件,需要接入IdeaXR
中进行脚本开发。
按照上述图片所示,单击 创建自定义插件 后,填写必要内容,选择我们编译好的MyPlugin.dll
文件和 第三方依赖的文件:
如果开发第三方插件有依赖项,请务必选择编译的dll中所依赖的库。
创建成功后,在编辑器下方 文件 中会显示如下,除native文件夹,其余文件为系统必备的文件,详情请查看自定义节点插件:
plugin.is 是脚本的配置文件。
MyPlugin.is 为功能脚本,主要的开发内容都在其内。
native 文件夹 如下所示:
bin 文件夹存放的内容是 选择的插件dll 和 选择的依赖dll
在插件脚本中调用
所有的环境都已经准备好了,现在开始获取我们动态库中编写的实例,在脚本中添加如下代码,
extends Spatial
func get_my_plugin(): // 获取动态库实例
var my_plugin = load("res://addons/my_plugin/native/MyPlugin.idns")
if my_plugin != null:
return my_plugin.new()
else :
print_debug("加载plugin出错")
return null
func _ready():
var my_plugin = get_my_plugin()
if my_plugin:
my_plugin.do_something(2) //调用动态库中的方法
var data = my_plugin.get_some_data() //调用动态库中的方法
func _physics_process(delta):
pass
之后,你就可以通过 my_plugin
操作我们在构建dll库中 创建的方法, 方法必须是在函数_register_methods
中绑定注册过的。
void MyScriptClass::_register_methods()
{
register_method("do_something", &MyScriptClass::do_something);
register_method("get_some_data", &MyScriptClass::get_some_data);
}
本教程到此就结束了,开始你的插件创作内容吧!