Home  >  Article  >  Backend Development  >  How to Safely Cast Between `void*` and a Pointer to a Member Function in C ?

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

Linda Hamilton
Linda HamiltonOriginal
2024-10-27 20:06:02173browse

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

Casting Between void* and a Pointer to Member Function

In the world of C programming, casting between void* and a pointer to a member function can be a real headache. Let's dive into a specific problem that illustrates this challenge.

Consider the following code snippet:

<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>

Here, GCC complains that the cast from void* to void (T::*)(int, int) is invalid. So, what's the solution?

Understanding the Problem

Understanding the problem requires delving deeper into the nature of pointers to member functions. Unlike regular pointers that point to addresses, pointers to member functions are much more complex. They contain information specific to the compiler implementation and the layout of class members.

Alternative Approaches

The truth is, you can't directly cast void* to a pointer to a member function. The suggested solution involves wrapping the member function in a regular function and returning that instead. Here's how:

<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>

This approach works because we are now casting to a regular function pointer, which can be stored in void* and retrieved without issue.

The above is the detailed content of How to Safely Cast Between `void*` and a Pointer to a Member Function in C ?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn