首頁  >  文章  >  後端開發  >  如何安全地將 void* 轉換為 C 中成員函數的指標?

如何安全地將 void* 轉換為 C 中成員函數的指標?

Patricia Arquette
Patricia Arquette原創
2024-10-28 06:07:30571瀏覽

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

轉換困難:Void* 和指向成員函數的指標

在程式設計領域,不同資料型別之間的轉換通常會帶來挑戰,尤其是當處理指向成員函數的指標時。本文深入探討了在嘗試建立與 Lua 解釋器互動的 C 函式庫時遇到的問題,其中將 void* 轉換為指向成員函數的指標構成了重大障礙。

有問題的程式碼嘗試註冊一個C 物件作為LuaObject 並向該物件添加成員函數:

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

但是,以下函數導致了問題:

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

問題在於編譯器的抱怨:無法將void 轉換為指向成員函數的指標。指向成員的指針是特定的,不能直接轉換為常規指針,如void.

要解決此問題,解決方案是將成員函數包裝在常規函數中,而不是使用指向成員的指針。此方法涉及創建一個自由函數,該函數接受物件作為其第一個參數並在內部呼叫成員函數。

這是使用此方法的函數的修改版本:

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

透過包裝成員函數,我們避免了將void* 轉換為指向成員函數的指針,解決了在這兩種資料類型之間進行轉換時遇到的問題。

以上是如何安全地將 void* 轉換為 C 中成員函數的指標?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn