Casting entre void* et un pointeur vers une fonction membre
Dans le monde de la programmation C, le casting entre void* et un pointeur vers une fonction membre la fonction membre peut être un véritable casse-tête. Examinons un problème spécifique qui illustre ce défi.
Considérez l'extrait de code suivant :
<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>
Ici, GCC se plaint que la conversion de void* en void (T::*) (int, int) n'est pas valide. Alors, quelle est la solution ?
Comprendre le problème
Comprendre le problème nécessite d'approfondir la nature des pointeurs vers les fonctions membres. Contrairement aux pointeurs classiques qui pointent vers des adresses, les pointeurs vers des fonctions membres sont beaucoup plus complexes. Ils contiennent des informations spécifiques à l'implémentation du compilateur et à la disposition des membres de la classe.
Approches alternatives
La vérité est que vous ne pouvez pas directement lancer void* vers un pointeur à une fonction membre. La solution suggérée consiste à envelopper la fonction membre dans une fonction régulière et à la renvoyer à la place. Voici comment :
<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>
Cette approche fonctionne car nous convertissons maintenant un pointeur de fonction standard, qui peut être stocké dans void* et récupéré sans problème.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!