c++静态内部类_UnLua静态绑定解析

cf033b73f8430239600c95c5d9db3179.png

之前分析了UnLua的实现

南京周润发:UnLua解析(一)Object绑定lua​zhuanlan.zhihu.com
4a2ae841e8714095ea5629da8246a21f.png

这些内容着重于使用UE4反射实现,UnLua也支持静态绑定,可以作为反射机制的补充,扩展更多功能。UnLua静态导出实现中使用了很多C++11和模板技术,因此看起来不太直观,本文也没有深入太多细节,只从总体实现上进行解析。

宏展开

静态导出使用C++宏实现,不能轻易看出实现细节,因此我们先通过一个把宏展开的例子,来看UnLua到底做了什么。

static const luaL_Reg UObjectLib[] =
{
    
    {
     "Load", UObject_Load },
    {
     "IsValid", UObject_IsValid },
    {
     "GetName", UObject_GetName },
    {
     "GetOuter", UObject_GetOuter },
    {
     "GetClass", UObject_GetClass },
    {
     "GetWorld", UObject_GetWorld },
    {
     "IsA", UObject_IsA },
    {
     "Destroy", UObject_Destroy },
    {
     "__eq", UObject_Identical },
    {
     "__gc", UObject_Delete },
    {
     nullptr, nullptr }
};

UObjectLib数组定义了一些导出到lua的方法,看起来是lua原生导出C模块方法,没什么特别的。

最下面几个宏实现了导出,逐个分析一下。

首先是BEGIN_EXPORT_REFLECTED_CLASS(UObject),定义会转到BEGIN_EXPORT_CLASS_EX宏,这是一个通用的Class导出实现。这里bIsReflected为true,Name和Type为UObject,其余都为空。

#define BEGIN_EXPORT_CLASS_EX(bIsReflected, Name, Suffix, Type, SuperTypeName, ...) 
    struct FExported##Name##Suffix##Helper 
    { 
        typedef Type ClassType; 
        static FExported##Name##Suffix##Helper StaticInstance; 
        UnLua::TExportedClass<bIsReflected, Type, ##__VA_ARGS__> *ExportedClass; 
        ~FExported##Name##Suffix##Helper() 
        { 
            delete ExportedClass; 
        } 
        FExported##Name##Suffix##Helper() 
            : ExportedClass(nullptr) 
        { 
            UnLua::TExportedClass<bIsReflected, Type, ##__VA_ARGS__> *Class = (UnLua::TExportedClass<bIsReflected, Type, ##__VA_ARGS__>*)UnLua::FindExportedClass(#Name); 
            if (!Class) 
            { 
                ExportedClass = new UnLua::TExportedClass<bIsReflected, Type, ##__VA_ARGS__>(#Name, SuperTypeName); 
                UnLua::ExportClass((UnLua::IExportedClass*)ExportedClass); 
                Class = ExportedClass; 
            }

可以看到定义了一个struct,宏展开后名称为FExportedUObjectHelper,内部包含静态类型StaticInstance和TExportedClass类型属性ExportedClass,然后是析构函数与一半构造函数。构造函数中会创建TExportedClass类型变量ExportedClass,并执行ExportClas函数进行导出,内部具体细节下面再分析。

然后看ADD_LIB(UObjectLib)

#define ADD_LIB(Lib) 
            Class->AddLib(Lib);

很简单,像是往ExportedClass里注册函数。

之后是END_EXPORTED_CLASS()

#define END_EXPORT_CLASS(...) 
        } 
    };

用于结束构造函数和类定义

最后是IMPLEMENT_EXPORTED_CLASS

#define IMPLEMENT_EXPORTED_CLASS(Name) 
    FExported##Name##Helper FExported##Name##Helper::StaticInstance;

用于创建静态变量StaticInstance

类结构

这里看下unlua实现静态导出所用类结构,可以先了解这些概念,不用细究实现细节。

首先是实现C++类型静态导出的类,比如上面看到的TExportedClass类,相关结构如下:

42de54adb24ba48a376cad83213e8f65.png

IExportedClass

属于interface,静态导出类都要继承它,里面定义了Register,AddLib等基本接口。

TExportedClassBase

实现了IExportedClass的接口,属于基本静态导出类,实现可注册类和导出lua原生C模块功能

成员:

FString Name

Fname ClassName

TArray<IExportedProperty*> Properties 导出的属性

Tarray<IExportedFunction*> Functions 导出的方法

Tarray<IExportedFunction*> GlueFunctions 导出的胶水方法

接口:

AddLib():添加lua原生C模块

Register():注册自己和相关函数

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值