Lua 如何在 C++ 中将 void* 指针传递给 lua && 将其传回C++



现在我想向Lua传递一个void*指针,使用userdata?如何做到这一点?

顺便说一句,我使用了luabind,但它不能将void*指针传递到Lua堆栈,这很烦人!你们能帮我吗?

struct Event
{
A* a;
B* b;
...
};
Event *e;
void* instance = (void*)e;

// param is a parameter that is passed from Lua script. param is a Event object. And I cast it into a void* type
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;

让我们先回答您的实际问题,然后再讨论为什么不应该这样做。

LuaBind是一个用于将C++函数和对象绑定到Lua的工具。void*既不是函数,也不是对象。从字面上讲,它是一个指向nothing的指针。因此,它对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将其传递回以便您可以检索它,只需创建一个函数,该函数将luabid::对象作为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*。即使WorkEventEvent的派生类,也不能将其直接强制转换为该类。你必须先把它变成Event*。此外,一旦您有了Event*,就应该使用dynamic_cast来进行下转换。

其次,停止为此使用void*s。如果所有事件都是从Event*派生的,那么只需传递一个Event*并在适当的情况下使用dynamic_cast。如果没有,那么你应该使用boost::any(LuaBind需要Boost,所以很明显你已经在使用它了)。你不仅可以将其绑定到LuaBind(因为它是一种实际类型),而且使用它更自然。

它有内置的保护功能,可以完全避免代码以前遇到的问题;如果在只给它一个Event的情况下尝试将它强制转换为WorkEvent,它将抛出异常。

我们不直接在lua中使用void*。这里我们用c函数调用lua函数,然后用lua函数调用c函数在第一个c中,我们将一个void*传递给lua函数则lua将void*传递给2nd c函数。

但是我们发现我们不能把一片空白传给lua当我们添加default_converter void*时。

namespace luabind
{
template <>
struct default_converter<void*> : native_converter_base<void*>
{
static int compute_score(lua_State * L, int index)
{
// this function will return 0 or -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

最新更新