首页  >  文章  >  后端开发  >  如何在 C 中的 `void*` 和指向成员函数的指针之间安全地进行转换?

如何在 C 中的 `void*` 和指向成员函数的指针之间安全地进行转换?

Linda Hamilton
Linda Hamilton原创
2024-10-27 20:06:02173浏览

How to Safely Cast Between `void*` and a Pointer to a Member Function in C  ?

void* 和指向成员函数的指针之间的转换

在 C 编程世界中,void* 和指向成员函数的指针之间的转换成员函数可能是一个真正令人头痛的问题。让我们深入研究一个具体问题来说明这一挑战。

考虑以下代码片段:

<code class="cpp">template <class T>
int call_int_function(lua_State *L) 
{
    void (T::*method)(int, int) = reinterpret_cast<void (T::*)(int, int)>(lua_touserdata(L, lua_upvalueindex(1))); // <-- problematic line
    T *obj = reinterpret_cast<T *>(lua_touserdata(L, 1));

    (obj->*method)(lua_tointeger(L, 2), lua_tointeger(L, 3));
    return 0;
}</code>

这里,GCC 抱怨从 void* 到 void (T::*) 的转换(int, int) 无效。那么,解决方案是什么?

理解问题

理解问题需要更深入地研究成员函数指针的本质。与指向地址的常规指针不同,指向成员函数的指针要复杂得多。它们包含特定于编译器实现和类成员布局的信息。

替代方法

事实是,您不能直接将 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* 中并毫无问题地检索。

以上是如何在 C 中的 `void*` 和指向成员函数的指针之间安全地进行转换?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn