LuaBridge移除反射字符串键后 Lua脚本如何实现类反射
LuaBridge 恢复脚本侧类反射能力实现方案
核心实现逻辑
LuaBridge 2.1版本之后移除__parent/__class等特殊键的本质是屏蔽了C侧存储的类元表访问入口,我们可以通过C侧自定义导出辅助函数,主动将类元表结构暴露到Lua侧,无需修改LuaBridge源码即可恢复反射能力。
C侧实现代码
#include <LuaBridge/LuaBridge.h> // 辅助函数:为导出的LuaBridge类附加反射元字段 template <class T> void enableLuaReflection(luabridge::Namespace& ns, const char* className) { // 获取LuaBridge生成的类元表 lua_State* L = ns.state(); luabridge::push<T>(L, nullptr); int userdataIdx = lua_gettop(L); if (lua_getmetatable(L, userdataIdx)) { // 主动暴露__class字段,存储类名 lua_pushstring(L, "__class"); lua_pushstring(L, className); lua_rawset(L, -3); // 主动暴露__propget/__propset字段,对应属性读写表 lua_pushstring(L, "__propget"); lua_rawgetp(L, -2, luabridge::detail::getPropgetKey()); lua_rawset(L, -3); lua_pushstring(L, "__propset"); lua_rawgetp(L, -2, luabridge::detail::getPropsetKey()); lua_rawset(L, -3); // 主动暴露__parent字段,对应父类元表 lua_pushstring(L, "__parent"); lua_rawgetp(L, -2, luabridge::detail::getParentKey()); lua_rawset(L, -3); lua_pop(L, 1); // 弹出元表 } lua_pop(L, 1); // 弹出临时userdata } // 导出类示例 void exportClasses(lua_State* L) { auto ns = luabridge::getGlobalNamespace(L); // 正常导出你的自定义类 ns.beginClass<MyClass>("MyClass") .addConstructor<void(*)()>() .addProperty("id", &MyClass::getId, &MyClass::setId) .addFunction("doSomething", &MyClass::doSomething) .endClass(); // 调用辅助函数开启反射能力 enableLuaReflection<MyClass>(ns, "MyClass"); }
Lua侧使用示例
local obj = MyClass() -- 打印类名 print(obj.__class) -- 输出 MyClass -- 遍历所有可读属性 for k, v in pairs(obj.__propget) do print("可读属性:", k) end -- 遍历所有可写属性 for k, v in pairs(obj.__propset) do print("可写属性:", k) end -- 遍历父类结构 local parentMeta = obj.__parent while parentMeta do print("父类:", parentMeta.__class) parentMeta = parentMeta.__parent end
注意事项
- 该方案仅推荐在开发模式开启,生产环境如果不需要反射能力建议关闭该辅助函数调用,避免引入不必要的安全风险
- 若存在类继承关系,需要为每个继承层级的类都调用一次
enableLuaReflection函数,才能完整暴露整条继承链的反射信息
内容的提问来源于stack exchange,提问作者rpatters1
相关产品推荐
相关产品推荐

