2

现在我想传递一个void*指向 Lua 的指针,使用 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;
4

2 回答 2

6

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

LuaBind 是一个将 C++ 函数和对象绑定到 Lua 的工具。Avoid*既不是函数也不是对象。从字面上看,它是指向nothing的指针。因此,它对 LuaBind 没有真正的意义。所以你不能直接通过一个。

但是,您可以返回 a luabind::object,它可以表示任何 Lua 值。例如,一个 Lua 用户数据。这意味着您可以从您的 . 中创建一些轻量级用户数据void*,将其粘贴到 a 中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*)eC++ 不保证它可以工作。如果你将一个对象强制转换为 a void*,C++提供了一个保证,如果你将它强制转换为与以前完全相同的对象,则可以得到有用的东西。

您从 开始Event*,然后将其转换为void*。您可以做的唯一合法操作是将其转换回Event*. 即使WorkEvent是 的派生类Event,也不能直接将其强制转换为该类。你必须把它变成Event*第一个。此外,dynamic_cast一旦你有一个Event*.

其次,停止使用void*s 。如果您的所有事件都来自Event*,则只需传递 anEvent*dynamic_cast在适当的地方使用。如果不是,那么您应该使用boost::any(LuaBind 需要 Boost,所以显然您已经在使用它了)。您不仅可以将它绑定到 LuaBind(因为它是一个实际类型),而且使用起来更加自然。

它具有内置的保护功能,可以避免您的代码之前遇到的问题;如果您尝试将其强制转换为 aWorkEvent时仅给出 a Event,它将引发异常。

于 2012-11-20T06:58:56.963 回答
2

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

但是我们发现我们在添加default_converter void*的时候不能给lua传递一个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
于 2012-11-20T07:15:02.323 回答