转换挑战:void* 到成员函数指针
在追求 Lua 的易于使用的 C 对象绑定库时,在 void* 和指向成员函数的指针之间进行转换的任务成为一个巨大的障碍。在利用 GCC 4.4 时,开发人员遇到以下困境:
<code class="cpp">void (T::*method)(int, int) = reinterpret_cast<void (T::*)(int, int)>(lua_touserdata(L, lua_upvalueindex(1)));</code>
问题的症结就在这里。 GCC 明确反对尝试直接将 void* 转换为指向成员函数的指针,这一点从其强烈的抱怨中即可看出。
解锁解决方案:揭开成员函数包装器
规避这种强制转换僵局的关键在于认识到指向成员的指针无法无缝转换为 void* 或任何传统的指针类型。与直接引用内存位置的典型指针不同,指向成员的指针封装了更复杂的细节,因此需要一种替代方法。
经验丰富的 C 编程爱好者提出的解决方案涉及采用成员函数包装器的概念。通过将成员函数包装在以对象作为其初始参数的标准函数中,我们解锁了使用reinterpret_cast将void*转换为所需函数指针的能力。
示例性代码重构
为了说明此技术的强大功能,请考虑上述函数的以下修订版本:
<code class="cpp">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; }</code>
通过采用这种修改后的方法,我们有效地回避了 void* 之间的转换问题和指向成员函数的指针,使我们能够获得无缝 Lua 对象绑定的好处,而不会遇到任何转换陷阱。
以上是如何克服在 C 中将 void* 转换为成员函数指针的挑战?的详细内容。更多信息请关注PHP中文网其他相关文章!