Heim  >  Artikel  >  Backend-Entwicklung  >  Wie kann ich void* sicher in einen Zeiger auf eine Memberfunktion in C umwandeln?

Wie kann ich void* sicher in einen Zeiger auf eine Memberfunktion in C umwandeln?

Patricia Arquette
Patricia ArquetteOriginal
2024-10-28 06:07:30571Durchsuche

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

Umwandlungsschwierigkeiten: Void* und Zeiger auf Mitgliedsfunktionen

Im Bereich der Programmierung stellt das Umwandeln zwischen verschiedenen Datentypen oft eine Herausforderung dar beim Umgang mit Zeigern auf Mitgliedsfunktionen. Dieser Artikel befasst sich mit einem Problem, das beim Versuch, eine C-Bibliothek zu erstellen, die mit einem Lua-Interpreter kommuniziert, aufgetreten ist und bei dem die Konvertierung von void* in einen Zeiger auf eine Member-Funktion eine erhebliche Hürde darstellte.

Der fragliche Code versucht, a zu registrieren C-Objekt als LuaObject und fügen Sie diesem Objekt eine Mitgliedsfunktion hinzu:

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

Die folgende Funktion verursacht jedoch das Problem:

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

Das Problem liegt in der Beschwerde des Compilers: it void kann nicht in einen Zeiger auf eine Mitgliedsfunktion umgewandelt werden. Zeiger auf Mitglieder sind spezifisch und können nicht direkt in reguläre Zeiger wie void umgewandelt werden.

Um dieses Problem zu beheben, besteht die Lösung darin, die Mitgliedsfunktion in eine reguläre Funktion einzuschließen, anstatt einen Zeiger auf ein Mitglied zu verwenden. Bei diesem Ansatz wird eine freie Funktion erstellt, die das Objekt als erstes Argument akzeptiert und die Mitgliedsfunktion intern aufruft.

Hier ist eine modifizierte Version der Funktion, die diesen Ansatz verwendet:

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

Durch Umbrechen Mit der Member-Funktion vermeiden wir die Notwendigkeit, void* in einen Zeiger auf eine Member-Funktion umzuwandeln, und lösen so das Problem, das beim Umwandeln zwischen diesen beiden Datentypen aufgetreten ist.

Das obige ist der detaillierte Inhalt vonWie kann ich void* sicher in einen Zeiger auf eine Memberfunktion in C umwandeln?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn