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

Comment convertir en toute sécurité void* en un pointeur vers une fonction membre en C ?

Patricia Arquette
Libérer: 2024-10-28 06:07:30
original
698 Les gens l'ont consulté

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

Difficultés de conversion : vide* et pointeur vers les fonctions membres

Dans le domaine de la programmation, la conversion entre différents types de données présente souvent des défis, en particulier lorsqu'il s'agit de pointeurs vers des fonctions membres. Cet article se penche sur un problème rencontré lors de la tentative de création d'une bibliothèque C qui s'interface avec un interpréteur Lua, où la conversion de void* en un pointeur vers une fonction membre posait un obstacle important.

Le code en question tente d'enregistrer un C en tant que LuaObject et ajoutez une fonction membre à cet objet :

template <class T>
LuaObject<T> lobj = registerObject(L, "foo", fooObject);
lobj.addField(L, "bar", &amp;Foo::bar);
Copier après la connexion

Cependant, la fonction suivante à l'origine du problème :

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

    (obj->*method)(lua_tointeger(L, 2), lua_tointeger(L, 3));
    return 0;
}
Copier après la connexion

Le problème réside dans la plainte du compilateur : il ne peut pas convertir void en un pointeur vers une fonction membre. Les pointeurs vers les membres sont spécifiques et ne peuvent pas être directement convertis en pointeurs réguliers comme void.

Pour résoudre ce problème, la solution consiste à envelopper la fonction membre dans une fonction régulière au lieu d'utiliser un pointeur vers un membre. Cette approche implique la création d'une fonction libre qui accepte l'objet comme premier argument et appelle la fonction membre en interne.

Voici une version modifiée de la fonction utilisant cette approche :

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

En encapsulant la fonction membre, nous évitons d'avoir à convertir void* en un pointeur vers une fonction membre, résolvant ainsi le problème rencontré lors du casting entre ces deux types de données.

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