在void *和指向成员函数的指针之间进行转换 [英] Casting between void * and a pointer to member function
问题描述
我目前使用GCC 4.4,我有相当的头痛转换void *和指向成员函数的指针。我试图写一个易于使用的库来绑定C ++对象到Lua解释器,如下:
I'm currently using GCC 4.4, and I'm having quite the headache casting between void * and a pointer to member function. I'm trying to write an easy-to-use library for binding C++ objects to a Lua interpreter, like so:
LuaObject<Foo> lobj = registerObject(L, "foo", fooObject);
lobj.addField(L, "bar", &Foo::bar);
我已经做了大部分工作,除了下面的功能函数签名,直到我有机会概括它):
I've got most of it done, except for the following function (which is specific to a certain function signature until I have a chance to generalize it):
template <class T>
int call_int_function(lua_State *L)
{
// this next line is problematic
void (T::*method)(int, int) = reinterpret_cast<void (T::*)(int, int)>(lua_touserdata(L, lua_upvalueindex(1)));
T *obj = reinterpret_cast<T *>(lua_touserdata(L, 1));
(obj->*method)(lua_tointeger(L, 2), lua_tointeger(L, 3));
return 0;
}
对于不熟悉Lua的人, lua_touserdata L,lua_upvalueindex(1))
获取与闭包相关联的第一个值(在这种情况下,它是成员函数的指针),并将其作为void *
。 GCC抱怨void *
- > void(T :: *)(int,int)是无效的转换。关于如何解决这个问题的任何想法?
For those of you unfamiliar with Lua, lua_touserdata(L, lua_upvalueindex(1))
gets the first value associated with a closure (in this case, it's the pointer to member function) and returns it as a void *
. GCC complains that void *
-> void (T::*)(int, int) is an invalid cast. Any ideas on how to get around this?
推荐答案
您无法将指向成员的指针转换为 void *
或任何其他常规指针类型。指针到成员不是常规指针的地址。你最有可能需要做的是将成员函数包装在一个常规函数中。 C ++常见问题解答版本对此进行了详细说明。主要问题是实现指针到成员所需的数据不只是一个地址,实际上不同
You cannot cast a pointer-to-member to void *
or to any other "regular" pointer type. Pointers-to-members are not addresses the way regular pointers are. What you most likely will need to do is wrap your member function in a regular function. The C++ FAQ Lite explains this in some detail. The main issue is that the data needed to implement a pointer-to-member is not just an address, and in fact varies tremendously based on the compiler implementation.
我假设你可以控制用户数据 lua_touserdata
正在返回。它不能是指向成员的指针,因为没有合法的方式来获取此信息。但你还有其他选择:
I presume you have control over what the user data lua_touserdata
is returning. It can't be a pointer-to-member since there isn't a legal way to get this information back out. But you do have some other choices:
-
最简单的选择是将你的成员函数包装在一个自由函数中, 。该自由函数应该将对象作为其第一个参数。请参阅下面的代码示例。
The simplest choice is probably to wrap your member function in a free function and return that. That free function should take the object as its first argument. See the code sample below.
使用类似于 Boost.Bind的mem_fun 来返回一个函数对象,你可以正确的模板。我看不到这更容易,但它会让你关联更多的状态与函数return如果你需要。
Use a technique similar to that of Boost.Bind's mem_fun to return a function object, which you can template on appropriately. I don't see that this is easier, but it would let you associate the more state with the function return if you needed to.
这里是使用第一种方式重写你的函数:
Here's a rewrite of your function using the first way:
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 *和指向成员函数的指针之间进行转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!