轉換困難:Void* 和指向成員函數的指標
在程式設計領域,不同資料型別之間的轉換通常會帶來挑戰,尤其是當處理指向成員函數的指標時。本文深入探討了在嘗試建立與 Lua 解釋器互動的 C 函式庫時遇到的問題,其中將 void* 轉換為指向成員函數的指標構成了重大障礙。
有問題的程式碼嘗試註冊一個C 物件作為LuaObject 並向該物件添加成員函數:
template <class T> LuaObject<T> lobj = registerObject(L, "foo", fooObject); lobj.addField(L, "bar", &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中文網其他相關文章!