UE4学习之路3:Puerts用ts调用C++
简介:ts怎么调用ue4中的类呢?
首先,puerts已经辅佐我们生成了大部门的类:是指UCLASS,USTRUCT标识表记标帜UPPROPERTY,UFUNCTION的属性、方式,可以直接在ts中包含库ue,就能使用对应类提供的方式。其他类想使用怎么去措置呢。
比如我们可能使用某些第三方库只有C++版本,那么关于第三方库怎么在ts脚本中调用呢?比如网络库,我们在ts脚本经常会调用发送网络动静函数,必需颠末c++调用第三方库来发出去。
或者我们本身写了一个担任ue4的某个子类,但愿可以被ts访谒到。
1. 普通C++类:
首先感激大佬的无私付出,才能使用Puerts,贴出大佬的文章:
https://github.com/Tencent/puerts/blob/master/doc/unreal/template_binding.md
说下工程的具体法式:
首先还是之前的项目,我们在Source/InstallPuerts的目录下,创建两个文件:Calc.h 和Calc.cpp文件。创建成功后,添加如下代码:
// .h 文件
#pragma once
class CalA
{
public:
static int32_t Add(int32_t a, int32_t b)
{
return a + b;
}
int32_t Get()
{
return m_c;
}
int m_c;
private:
int m_d;
};
class CalB
{
public:
static int32_t Add(int32_t a, int32_t b)
{
return a + b;
}
private:
};
// .cpp文件
#include ”Calc.h”
#include ”Binding.hpp”
UsingCppType(CalA);
UsingCppType(CalB);
struct AutoRegisterForCalAB
{
AutoRegisterForCalAB()
{
puerts::DefineClass<CalA>().Function(”AddA”, MakeFunction(&CalA::Add)).Register();
puerts::DefineClass<CalB>().Function(”AddF”, MakeFunction(&CalB::Add)).Register();
}
};
AutoRegisterForCalAB _AutoRegisterForCalAB__;
这两个类的声明相信大师都看得懂,主要在cpp文件,首先要包含生成ts的代码的头文件,然后固定格式,使用UsingCppType是在声明要生成ts。然后主要代码是
puerts::DefineClass<类名>().Functiong(”生成的ts的函数名”,使用的函数).Register();
AutoRegisterForCalAB这个布局体可有可无,其实就是通过布局体的自动创建过程来达到调用函数的目的。这两个函数也可以放到其他启动的函数处所。
加完之后,打开UE4项目工程,还是之前我们创建的工程。点击编译,完成后再点击ue.d.ts按钮,在目录Plugins/Puerts/Typing/cpp中,就生成了文件index.d.ts:
declare module ”cpp” {
import * as UE from ”ue”
import {$Ref, $Nullable} from ”puerts”
class CalA {
static AddA(p0: number, p1: number) :number;
}
class CalB {
static AddF(p0: number, p1: number) :number;
}
} 但愿大师都按照流程生成了这个文件。
如何使用呢,就正常引用cpp文件,调用就好了。
import * as UE from 'ue'
import {$ref, $unref, $set, argv, on, toManualReleaseDelegate, releaseManualReleaseDelegate} from 'puerts';
import * as cpp from 'cpp'
console.log(”Quick start ---------------aaaaaaaaaaaaa----------------”);
let Cala = cpp.CalA;
console.log(Cala.AddA(12, 34)); UE4中运行:查看控制台:
成功输出成果46。
有个处所需要注意:就是在执行ue.d.ts生成ts代码的时候,如果是新增类,或者改削类的名字等,可以生成正确的ts文件,如果是删掉某个方式,则会漏掉删除操作,且封锁ue4的时候会报出ue4崩溃的问题,解决方式是封锁ue4改削可以达到效果。这个我咨询了puerts的创建者车大佬,感激大佬的回答,应该是ue4的live reload的功能不完善,不是puerts的问题
重头戏:说下方式或者属性如何转化:以后使用法式员基础技能:复制粘贴模板。
// Binging.hpp 文件内定义
//
// 撑持注册的方式
ClassDefineBuilder<T>& Constructor(InitializeFuncType constructor, int length, const CFunctionInfo** infos);
ClassDefineBuilder<T>& Function(const char* name, FunctionCallbackType func, const CFunctionInfo* info);
ClassDefineBuilder<T>& Function(const char* name, FunctionCallbackType func, int length, const CFunctionInfo** infos)
ClassDefineBuilder<T>& Method(const char* name, FunctionCallbackType func, const CFunctionInfo* info);
ClassDefineBuilder<T>& Method(const char* name, FunctionCallbackType func, int length, const CFunctionInfo** infos)
ClassDefineBuilder<T>& Property(const char* name, FunctionCallbackType getter, FunctionCallbackType setter = nullptr, const char* type = nullptr)
// 生成特定参数的方式
#define MakeConstructor(T, ...) ::puerts::template ConstructorWrapper<T, ##__VA_ARGS__>
#define MakeGetter(M) &(::puerts::PropertyWrapper<decltype(M), M>::getter)
#define MakeSetter(M) &(::puerts::PropertyWrapper<decltype(M), M>::setter)
#define MakeProperty(M) &(::puerts::PropertyWrapper<decltype(M), M>::getter), &(::puerts::PropertyWrapper<decltype(M), M>::setter), ::puerts::PropertyWrapper<decltype(M), M>::info()
#define MakeFunction(M) &(::puerts::FuncCallWrapper<decltype(M), M>::call), ::puerts::FuncCallWrapper<decltype(M), M>::info()
#define SelectFunction(SIGNATURE, M) &(::puerts::FuncCallWrapper<SIGNATURE, M>::call), ::puerts::FuncCallWrapper<SIGNATURE, M>::info()
#define MakeCheckFunction(M) &(::puerts::FuncCallWrapper<decltype(M), M>::checkedCall), ::puerts::FuncCallWrapper<decltype(M), M>::info()
#define MakeOverload(SIGNATURE, M) puerts::FuncCallWrapper<SIGNATURE, M>
#define CombineOverloads(...) &::puerts::OverloadsCombiner<__VA_ARGS__>::call, ::puerts::OverloadsCombiner<__VA_ARGS__>::length, ::puerts::OverloadsCombiner<__VA_ARGS__>::infos()
#define CombineConstructors(...) &::puerts::ConstructorsCombiner<__VA_ARGS__>::call, ::puerts::ConstructorsCombiner<__VA_ARGS__>::length, ::puerts::ConstructorsCombiner<__VA_ARGS__>::infos()
// 怎么使用:
// 构造函数:仅有一个int参数的构造函数
puerts::DefineClass<CalA>()
.Constructor<int>()
.Register();
// 构造函数:多个构造函数
puerts::DefineClass<CalA>()
.Constructor(CombineConstructors(
MakeConstructor(CalA, int32_t, int32_t),
MakeConstructor(CalA)
))
.Register();
// 静态函数:单一函数
puerts::DefineClass<CalA>()
.Function(”Add”, MakeFunction(&CalA::Add))
.Register();
// 静态函数:多个重载函数,假设CalA有4个构造函数,参数分袂是下面4种
puerts::DefineClass<CalA>()
.Function(”Overload”, CombineOverloads(
MakeOverload(void(*)(), &CalA::Overload),
MakeOverload(void(*)(int32_t), &CalA::Overload),
MakeOverload(void(*)(int32_t, int32_t), &CalA::Overload),
MakeOverload(void(*)(std::string, int32_t), &CalA::Overload)
))
.Register();
// 成员函数: 无重载
puerts::DefineClass<CalA>()
.Method(”Add”, MakeFunction(&CalA::Add))
.Register();
// 成员函数: 多个重载,以及连着写法
puerts::DefineClass<CalA>()
.Method(”OverloadMethod”, CombineOverloads(
MakeOverload(int32_t(CalA::*)(), &CalA::OverloadMethod),
MakeOverload(int32_t(CalA::*)(int32_t), &CalA::OverloadMethod),
MakeOverload(uint32_t(CalA::*)(uint32_t), &CalA::OverloadMethod),
MakeOverload(int64_t(CalA::*)(int64_t), &CalA::OverloadMethod)
))
.Method(”GetSelf”, MakeFunction(&CalA::GetSelf))
.Register();
// 成员变量:
puerts::DefineClass<TestClass>()
.Property(”X”, MakeProperty(&TestClass::X))
.Property(”Y”, MakeProperty(&TestClass::Y))
.Register();
2. UE4的类:
本身编写的担任UE4的类,也必需在文件Source/XXX项目路径下,否则是没法子生成ts的,不外有些东西没必要生成ts的类,也别放在这个目录下,否则会生成ts代码。
担任的UE的类,声明为UFUNCTION和UPROPERTY的,不需要额外写注册的代码,只需ue4编译并点击ue.d.ts,就能生成ts代码,生成路径是:Plugins\Puerts\Typing\ue目录。
比如我写的:
就能引用到了:
// .h文件
#pragma once
#include ”ArrayBuffer.h”
#include ”CoreMinimal.h”
#include ”UObject/NoExportTypes.h”
#include ”TestObject.generated.h”
/**
*
*/
UCLASS()
class INSTALLPUERTS_API UMyTestObject : public UObject
{
GENERATED_BODY()
public:
UMyTestObject();
UFUNCTION(BlueprintCallable, meta = (DisplayName = ”Add”, ScriptName = ”Add”, Keywords = ”test”), Category = ”Test”)
int32 Add(int32 a, int32 b) const;
~UMyTestObject();
};
// .cpp文件
#include ”TestObject.h”
UMyTestObject::UMyTestObject()
{
}
UMyTestObject::~UMyTestObject()
{
}
int32 UMyTestObject::Add(int32 a, int32 b) const
{
return a+b;
} ts文件包含库ue就能访谒了。
下面说说非UFUNTION,和UPROPERTY怎么生成:
比如UObject的GetName,GetWorld不是UFUNCTION
#include ”CoreMinimal.h”
#include ”Binding.hpp”
#include ”UEDataBinding.hpp”
UsingUClass(UObject)
UsingUClass(UWorld) // for return type
puerts::DefineClass<UObject>()
.Method(”GetName”, SelectFunction(FString (UObjectBaseUtility::*)() const, &UObjectBaseUtility::GetName))
.Method(”GetWorld”, MakeFunction(&UObject::GetWorld))
.Register(); 这里因为是UE的类,所以不能使用UsingCppType,要使用UsingUClass,后面的函数基本一样。
页:
[1]