在Luabind中的自定义构造函数
2011-11-13 22:28:47
收藏:0
阅读:159
评论:2
我正在使用Luabind将C++ API绑定到Lua。我有一些无法直接创建的对象,而是必须在另一个线程上创建。我目前通过定义一个名为create
的“静态”成员来处理这个问题,该成员会一直yield,直到对象被创建:
luabind::class_<Foo>("Foo")
.scope
[
luabind::def("create", &someCreateMethod, luabind::yield)
]
这个方法可行,但缺点是使客户端API变得复杂。对于这些类,您无法以正常方式创建它们(例如,local f = Foo()
),而是需要执行local f = Foo.create()
。
是否可能定义一个Luabind构造函数,它不实际调用C++构造函数,而是调用另一个返回构造对象的函数(并在此期间可以yield)?我已尝试定义__init
和__call
的绑定(后者在scope
下定义了它,以定义它在类而不是实例上),但我没有成功。
原文链接 https://stackoverflow.com/questions/8115263
点赞
stackoverflow用户1879228
虽然 luabind 没有提供直接定义自定义构造函数的途径,但是通过一些技巧是可能的:
template<typename T,auto TCnstrct,typename ...TArgs>
static void custom_constructor(luabind::argument const &self_, TArgs... args)
{
using holder_type = luabind::detail::value_holder<T>;
luabind::detail::object_rep* self = luabind::touserdata<luabind::detail::object_rep>(self_);
void* storage = self->allocate(sizeof(holder_type));
self->set_instance(new (storage) holder_type(nullptr,TCnstrct(std::forward<TArgs>(args)...)));
}
template<typename T,auto TCnstrct,typename ...TArgs>
static void define_custom_constructor(lua_State *l)
{
auto *registry = luabind::detail::class_registry::get_registry(l);
auto *crep = registry->find_class(typeid(T));
assert(crep);
auto fn = luabind::make_function(l,&custom_constructor<T,TCnstrct,TArgs...>);
crep->get_table(l);
auto o = luabind::object{luabind::from_stack(l,-1)};
luabind::detail::add_overload(o,"__init",fn);
lua_pop(l,1);
}
这将允许您在类定义之后使用任何自由函数作为构造函数:
static void define_vector_class(lua_State *l)
{
auto modMath = luabind::module_(l,"math");
struct Vector
{
Vector()=default;
float x,y,z;
};
auto defVec = luabind::class_<Vector>("Vector");
modMath[defVec];
// 定义接受三个浮点型参数的自定义构造函数
define_custom_constructor<Vector,[](float x,float y,float z) -> Vector {
Vector v;
v.x = x;
v.y = y;
v.z = z;
return v;
},float,float,float>(l); // 构造函数参数类型也必须在模板参数列表中指定
}
在 luabind 的 deboostified 版本中进行了测试(https://github.com/decimad/luabind-deboostified),但是它也应该适用于常规版本。
2021-08-28 15:58:17
评论区的留言会收到邮件通知哦~
推荐文章
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
- 如何编写 Lua 模式将字符串(嵌套数组)转换为真正的数组?
Luabind 中的构造函数必须是实际的 C++ 类构造函数。所以你得处理一下略微奇怪的 API。
如果你只关心如何将
Foo
用作构造函数方法,那么可以这样做。将你的 C++ 类Foo
登记为FooLua
,并将someCreateMethod
注册为 Lua 的自由函数Foo
,而不是FooLua
的成员。因此,对于用户而言,Foo
是 Lua 类Foo
的构造函数。但这会限制你赋予
Foo
其他静态属性(如成员等)的能力。但你可以通过一些直接的 Lua API 编码来实现。你可以创建一个空表Foo
,为其创建一个 metatable,并将其中的__index
和__newindex
调用转发到FooLua
。同样地,你可以覆盖这个 metatable 的__call
,将构造转发到Foo.create
。