Maison  >  Article  >  développement back-end  >  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
Patricia Arquetteoriginal
2024-10-28 06:07:30571parcourir

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

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

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

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!

Déclaration:
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