Вот то, как я недавно сделал это. Не прекрасный семантически, но сделали задание.
<div class="container" style="position: relative">
<img style="z-index: 32; left: 8px; position: relative;" alt="bottom image" src="images/bottom-image.jpg">
<div style="z-index: 100; left: 72px; position: absolute; top: 39px">
<img alt="top image" src="images/top-image.jpg"></div></div>
Вы не можете привести указатель на член к void *
или к любому другому «обычному» типу указателя. Указатели на члены не являются адресами, как обычные указатели. Что вам, скорее всего, нужно будет сделать, так это обернуть вашу функцию-член в обычную функцию. В C ++ FAQ Lite это подробно объясняется. Основная проблема заключается в том, что данные, необходимые для реализации указателя на член, - это не просто адрес, и на самом деле сильно различается в зависимости от реализации компилятора.
Я предполагаю, что вы контролируете, что данные пользователя lua_touserdata
возвращаются. Это не может быть указатель на член, поскольку нет законного способа вернуть эту информацию. Но у вас есть и другие варианты:
Самый простой вариант - обернуть вашу функцию-член в бесплатную функцию и вернуть ее. Эта бесплатная функция должна принимать объект в качестве первого аргумента. См. Пример кода ниже.
Используйте технику, аналогичную методу mem_fun Boost.Bind, чтобы вернуть объект функции, для которого можно создать шаблон. Я не думаю, что это проще, но это позволило бы вам связать состояние more с функцией return, если вам нужно.
Вот перезапись вашей функции с использованием первого способа:
template <class T>
int call_int_function(lua_State *L)
{
void (*method)(T*, int, int) = reinterpret_cast<void (*)(T*, int, int)>(lua_touserdata(L, lua_upvalueindex(1)));
T *obj = reinterpret_cast<T *>(lua_touserdata(L, 1));
method(obj, lua_tointeger(L, 2), lua_tointeger(L, 3));
return 0;
}
В качестве обходного пути, учитывая ограничения преобразования указателя на функцию-член в void *
, вы можете заключить указатель функции в небольшую структуру, выделенную в куче, и поместить указатель на эту структуру в ваших пользовательских данных Lua:
template <typename T>
struct LuaUserData {
typename void (T::*MemberProc)(int, int);
explicit LuaUserData(MemberProc proc) :
mProc(proc)
{ }
MemberProc mProc;
};
LuaObject<Foo> lobj = registerObject(L, "foo", fooObject);
LuaUserData<Foo>* lobj_data = new LuaUserData<Foo>(&Foo::bar);
lobj.addField(L, "bar", lobj_data);
// ...
template <class T>
int call_int_function(lua_State *L)
{
typedef LuaUserData<T> LuaUserDataType;
typedef typename LuaUserDataType::MemberProc ProcType;
// this next line is problematic
LuaUserDataType* data =
reinterpret_cast<LuaUserDataType*>(lua_touserdata(L, lua_upvalueindex(1)));
T *obj = reinterpret_cast<T *>(lua_touserdata(L, 1));
(obj->*(data.mMemberProc))(lua_tointeger(L, 2), lua_tointeger(L, 3));
return 0;
}
Я не разбираюсь в Lua, поэтому я, вероятно, что-то пропустил в приведенном выше примере. Имейте в виду, что если вы пойдете по этому пути, вам придется управлять распределением LuaUserData.