Heim  >  Artikel  >  Backend-Entwicklung  >  Wie kann man in C sicher zwischen „void*“ und einem Zeiger auf eine Member-Funktion umwandeln?

Wie kann man in C sicher zwischen „void*“ und einem Zeiger auf eine Member-Funktion umwandeln?

Linda Hamilton
Linda HamiltonOriginal
2024-10-27 20:06:02173Durchsuche

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

Umwandlung zwischen void* und einem Zeiger auf eine Mitgliedsfunktion

In der Welt der C-Programmierung erfolgt die Umwandlung zwischen void* und einem Zeiger auf a Member-Funktionen können echte Kopfschmerzen bereiten. Lassen Sie uns in ein spezifisches Problem eintauchen, das diese Herausforderung veranschaulicht.

Betrachten Sie den folgenden Codeausschnitt:

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

Hier beschwert sich GCC darüber, dass die Umwandlung von void* in void (T::*) (int, int) ist ungültig. Also, was ist die Lösung?

Das Problem verstehen

Um das Problem zu verstehen, muss man sich tiefer mit der Natur von Zeigern auf Mitgliedsfunktionen befassen. Im Gegensatz zu regulären Zeigern, die auf Adressen zeigen, sind Zeiger auf Mitgliedsfunktionen viel komplexer. Sie enthalten spezifische Informationen zur Compiler-Implementierung und zum Layout der Klassenmitglieder.

Alternative Ansätze

Die Wahrheit ist, dass Sie void* nicht direkt in einen Zeiger umwandeln können zu einer Mitgliedsfunktion. Die vorgeschlagene Lösung besteht darin, die Memberfunktion in eine reguläre Funktion einzuschließen und diese stattdessen zurückzugeben. So geht's:

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

Dieser Ansatz funktioniert, weil wir jetzt auf einen regulären Funktionszeiger umwandeln, der in void* gespeichert und ohne Probleme abgerufen werden kann.

Das obige ist der detaillierte Inhalt vonWie kann man in C sicher zwischen „void*“ und einem Zeiger auf eine Member-Funktion 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