sluaunreal icon indicating copy to clipboard operation
sluaunreal copied to clipboard

插件支持Cast吗?

Open FTQZS opened this issue 5 years ago • 14 comments

图片 UE4的UFUNCTION有一个CustomThunk,可以使蓝图支持模板编程,我在lua中想获取派生自FTableRowBase的结构体对象,但报错了,只能获取到FTableRowBase对象,所以我在想有没有办法强转,或者lua中怎么使用本该给蓝图反射的CustomThunk实现模板化? 希望能帮我解答一下这两个问题,Cast还是比较常用的操作,如果slua不支持只能借助tolua吗?还有就是UE4的CustomThunk的模板编程在lua能用吗?

FTQZS avatar Jan 29 '20 19:01 FTQZS

你是需要一个c++里的Cast<>(UObject)的函数?

pangweiwei avatar Jan 31 '20 09:01 pangweiwei

C++里的Cast是不行吧,C++的Cast本身是一个泛型函数,开lua接口要实例化一个类型,lua最后得到的还是一个Parent指针,事实上我想要派生类的对象。

FTQZS avatar Jan 31 '20 09:01 FTQZS

你的这个需求没办法直接写一个通用函数搞定,你可以考虑自己写一个特例化导出函数实现FTableRowbase的转换为你需要的类型,FTableRowbase(包括FXxxx)的类型都没有反射信息,不支持动态的cast行为。

你提到的tolua是支持unity的吧?c#有很好的反射支持,所以很容易实现这个特性。

pangweiwei avatar Feb 01 '20 08:02 pangweiwei

tolua也是一种能lua和C++交互的方案,他们提供了Cast的接口。FindRow这个泛型函数和SpawnActor不一样,它内部是uint8指针用reinterpret_cast强转到目标类型的,我验证后也发现slua的确能从以基类指针返回出派生类的指针给lua,但FindRow却是原始的uint8指针强转的,根本不知道是哪个派生类,所以考虑lua是不是该提供一个Cast接口。 至于大佬提到的特例化一个,一方面游戏里的配置表结构很多,已经频繁修改,而且不一定是C++里的数据结构,还有策划自己配的蓝图的UStruct,特例化还是个下下策吧? 而且我也想过试试特例化,但在插件中include自己定义Struct是查找不到目录,然后我转向在UGameInstance的Init里导出FindRow函数,却编译不通过,不知道问题在哪。

FTQZS avatar Feb 01 '20 08:02 FTQZS

downcast能力确实是欠奉的,这个是已知问题。

https://github.com/Tencent/sluaunreal/wiki/CppBinding-%E7%AE%80%E5%8D%95%E4%BD%BF%E7%94%A8%E8%AF%B4%E6%98%8E#cppbinding%E7%9A%84%E9%99%90%E5%88%B6

关于你编译不过的问题,你可以贴出你的代码,你得到的错误信息

pangweiwei avatar Feb 01 '20 11:02 pangweiwei

我趁放假在家,做一下cppbinding的down cast能力吧。这个已经提供了基础能力设施了,实现起来不复杂。

pangweiwei avatar Feb 01 '20 11:02 pangweiwei

好的,感谢大佬,本来我想抄一下tolua的实现方式,但发现和tolua的耦合性太多,还是官方能支持一下最好。

FTQZS avatar Feb 01 '20 11:02 FTQZS

图片

在UGameInstance的Init里导出函数,编译通不过,什么原因呢?

FTQZS avatar Feb 01 '20 11:02 FTQZS

严重性 代码 说明 项目 文件 行 禁止显示状态 错误(活动) E0864 LuaCppBinding 不是模板 democpp D:\Download\sluaunreal-master\sluaunreal-master\Source\democpp\MyGameInstance.cpp 63

FTQZS avatar Feb 01 '20 11:02 FTQZS

在MyGameInstance.cpp里这样定义

#include "LuaCppBinding.h"
#include "Engine/DataTable.h"

namespace NS_SLUA {
	DefTypeName(FTableRowBase);
	
	void myExtension() {
		REG_EXTENSION_METHOD_WITHTYPE(UDataTable, "FindRow", &UDataTable::FindRow, FTableRowBase* (UDataTable::*)(FName, const FString&, bool) const);
	}
}

然后在Init函数里调用

NS_SLUA::myExtension();

pangweiwei avatar Feb 01 '20 13:02 pangweiwei

导出函数需要在命名空间NS_SLUA下啊,好吧

FTQZS avatar Feb 01 '20 15:02 FTQZS

今天我看了一下GetDataTableRowFromName函数的实现,和我想实现的cast机制不一样,我希望增加的cast机制是需要有一些侵入的修改的,但是这个FTableRowBase和其所有子类都无法侵入修改,所以实现不了cast。

pangweiwei avatar Feb 02 '20 10:02 pangweiwei

你的这个需求没办法直接写一个通用函数搞定,你可以考虑自己写一个特例化导出函数实现FTableRowbase的转换为你需要的类型,FTableRowbase(包括FXxxx)的类型都没有反射信息,不支持动态的cast行为。 你提到的tolua是支持unity的吧?c#有很好的反射支持,所以很容易实现这个特性。

大部分有USTRUCT标记的结构体也是有反射信息的,包括FTableRowbase

RPG3D avatar Feb 12 '20 08:02 RPG3D

你的这个需求没办法直接写一个通用函数搞定,你可以考虑自己写一个特例化导出函数实现FTableRowbase的转换为你需要的类型,FTableRowbase(包括FXxxx)的类型都没有反射信息,不支持动态的cast行为。 你提到的tolua是支持unity的吧?c#有很好的反射支持,所以很容易实现这个特性。

大部分有USTRUCT标记的结构体也是有反射信息的,包括FTableRowbase

大佬有实现Cast的思路?UStruct和UClass里都有UProperty和UFunction,但都要知道具体名字和类型才能还原对象的数据,FindPropertyByName要知道成员名字,ContainerPtrToValuePtr是模板函数要知道成员类型。

FTQZS avatar Feb 18 '20 03:02 FTQZS