Maison > développement back-end > C++ > Comment effectuer un cast en toute sécurité entre `void*` et un pointeur vers une fonction membre en C ?

Comment effectuer un cast en toute sécurité entre `void*` et un pointeur vers une fonction membre en C ?

Linda Hamilton
Libérer: 2024-10-27 20:06:02
original
271 Les gens l'ont consulté

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

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>
Copier après la connexion

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>
Copier après la connexion

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!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal