如何在C++中将void*指针传递给Lua,并将其传回C++
2012-11-20 7:6:9
收藏:0
阅读:155
评论:2
现在我想将一个void*指针传递给Lua,应该使用userdata吗?
如何做到这一点?
顺便说一句,我使用了luabind,但它无法将void*指针传递给Lua堆栈,这很烦人!你们能帮我吗?
struct Event
{
A* a;
B* b;
...
};
Event *e;
void* instance = (void*)e;
// param是从Lua脚本传递的参数,param是一个Event对象。我将其转换为void*类型
string Answer(void* param)
{
WorkEvent *pWorkEvent = static_cast<WorkEvent*>(param);
ASSERT_RET(pWorkEvent, NULL);
string call_id = pWorkEvent->GetCallId();
CCmThreadManager::TType thrd_id = pWorkEvent->GetHandleThrdID();
Coroutine *pco = pWorkEvent->m_pco;
点赞
用户1837970
我们不直接在 Lua 中使用 void*。
在这里,我们使用 C 函数调用 Lua 函数,然后 Lua 函数再调用 C 函数。
在第一个 C 函数中,我们将一个 void* 传递给 Lua 函数,然后 Lua 将 void* 传递给第二个 C 函数。
但是当我们添加默认转换器 void* 时,我们发现无法将 void* 传递给 Lua。
namespace luabind
{
template <>
struct default_converter<void*> : native_converter_base<void*>
{
static int compute_score(lua_State* L, int index)
{
// 此函数将返回 0 或 -1 (int)
return lua_type(L, index) == LUA_TLIGHTUSERDATA ? 0 : -1;
}
void* from(lua_State* L, int index)
{
return lua_touserdata(L, index);
}
void to(lua_State* L, void* value)
{
lua_pushlightuserdata(L, value);
}
};
} // namespace luabind
2012-11-20 07:15:02
评论区的留言会收到邮件通知哦~
推荐文章
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在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中获取用户配置主目录的跨平台方法
在讨论为什么你不应该这样做之前,让我们先回答你的实际问题。
LuaBind是将C++函数和对象绑定到Lua的工具。
void *既不是函数也不是对象。它确实是一个指向 空 的指针。因此,对于LuaBind来说,它没有实际含义。因此,您不能直接传递它。但是,您可以返回一个
luabind::object,该对象可以代表任何Lua值。例如,Lua用户数据。这意味着,您可以从您的void*中创建一些轻量级用户数据,将其放入luabind::object中,并从与LuaBind注册的函数中返回它。luabind::object RegisteredFunction(..., lua_State *L) { void *return_value = ...; lua_pushlightuserdata(L, return_value); luabind::object ret(luabind::from_stack(L, -1)); lua_pop(L, 1); return ret; }为了允许Lua返回它以便您可以检索它,只需创建一个以
luabind::object作为void*参数的函数即可:void OtherRegisteredFunction(..., luabind::object obj, ...) { assert(luabind::type(obj) == LUA_TLIGHTUSERDATA); obj.push(); void *param = lua_touserdata(obj.interpreter(), -1); lua_pop(obj.interpreter(), 1); }所以这就是如何传递这种类型的数据。现在这里是为什么你不应该这样做。
首先,你的代码是有问题的:
WorkEvent *pWorkEvent = static_cast<WorkEvent*>(param);假设你的
param来自这一行:void* instance = (void*)e,C++不能保证这将起作用。如果你将一个对象转换为void *,C++只提供一个保证,即如果你将它转换回 _完全相同的对象_,它会提供一些有用的东西。你开始使用一个
Event*,然后转换成了void *。你唯一 合法 的操作是将其转回Event*。即使WorkEvent是Event的派生类,你也不能 直接 将其转换为那个类。您必须首先将其转回Event*。而且,一旦你有了一个Event*,你应该使用dynamic_cast来进行向下转型。其次,请停止为此使用
void*。如果您的所有事件都是从Event*派生的,则只需传递一个Event*并在适当的地方使用dynamic_cast。如果它们没有,那么您应该 使用boost::any(因为LuaBind需要Boost,所以显然您已经在使用它了)。你不仅可以将其绑定到LuaBind(因为它是一个实际类型),而且使用起来更加自然。它具有内置的保护措施,可以解决您的代码之前遇到的问题;如果您在只给出
Event时尝试将其转换为WorkEvent,它将抛出异常。