Now I want to pass a void* pointer to Lua, use userdata?
How to do this?
BTW, I used luabind, but it cannot pass a void* pointer to Lua stack, this is annoying! Could you guys help me?
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;
Let’s answer your actual question before getting into why you shouldn’t be doing this.
LuaBind is a tool for binding C++ functions and objects to Lua. A
void*is neither a function nor an object. It is, quite literally, a pointer to nothing. As such, it has no real meaning to LuaBind. So you cannot pass one directly.You can however return a
luabind::object, which can represent any Lua value. For example, a Lua userdata. Which means you can create some light userdata from yourvoid*, stick it into aluabind::objectand return it from a function you register with LuaBind.To allow Lua to pass it back so that you can retrieve it, simply create a function that takes a luabind::object as the
void*parameter:So that’s how you pass that kind of data. Now here’s why you shouldn’t do that.
First, your code is broken:
Assuming that your
paramcame from this line,void* instance = (void*)e, C++ doesn’t guarantee this to work. If you cast an object to avoid*, C++ only provides a guarantee of getting something useful back if you cast it to the exact same object as it was before.You started with an
Event*, then converted it to avoid*. The only legal operation you can do is to cast it back to anEvent*. Even ifWorkEventis a derived class ofEvent, you cannot cast it directly to that class. You have to turn it back into anEvent*first. Also, you should use adynamic_castto do the down-cast once you have anEvent*.Second, stop using
void*s for this. If all of your events are derived fromEvent*, then just pass anEvent*and usedynamic_castwhere appropriate. If they aren’t, then you should be usingboost::any(LuaBind requires Boost, so obviously you’re using it already). Not only will you be able to bind that to LuaBind (since it’s an actual type), it’s much more natural to work with.And it has built-in protection from exactly the problem your code had before; if you tried to cast it to a
WorkEventwhen it was given only anEvent, it would throw an exception.