Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimana untuk Membuang kekosongan* dengan Selamat kepada Penunjuk ke Fungsi Ahli dalam C ?

Bagaimana untuk Membuang kekosongan* dengan Selamat kepada Penunjuk ke Fungsi Ahli dalam C ?

Patricia Arquette
Patricia Arquetteasal
2024-10-28 06:07:30571semak imbas

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

Kesukaran Casting: Void* dan Penunjuk kepada Fungsi Ahli

Dalam bidang pengaturcaraan, penghantaran antara jenis data yang berbeza sering menimbulkan cabaran, terutamanya apabila berurusan dengan petunjuk kepada fungsi ahli. Artikel ini membincangkan isu yang dihadapi semasa cuba mencipta pustaka C yang antara muka dengan penterjemah Lua, yang menukar void* kepada penuding kepada fungsi ahli menimbulkan halangan yang ketara.

Kod yang dimaksudkan cuba mendaftarkan Objek C sebagai LuaObject dan tambahkan fungsi ahli pada objek itu:

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

Walau bagaimanapun, fungsi berikut menyebabkan isu:

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

Isunya terletak pada aduan pengkompil: ia tidak boleh membuang kekosongan ke penunjuk ke fungsi ahli. Penunjuk kepada ahli adalah khusus dan tidak boleh ditukar terus kepada penuding biasa seperti void.

Untuk menyelesaikan isu ini, penyelesaiannya ialah dengan membalut fungsi ahli dalam fungsi biasa dan bukannya menggunakan penuding kepada ahli. Pendekatan ini melibatkan penciptaan fungsi percuma yang menerima objek sebagai hujah pertamanya dan memanggil fungsi ahli secara dalaman.

Berikut ialah versi diubah suai fungsi menggunakan pendekatan ini:

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

Dengan membalut fungsi ahli, kami mengelakkan keperluan untuk menghantar kekosongan* ke penunjuk ke fungsi ahli, menyelesaikan isu yang dihadapi semasa menghantar antara dua jenis data ini.

Atas ialah kandungan terperinci Bagaimana untuk Membuang kekosongan* dengan Selamat kepada Penunjuk ke Fungsi Ahli dalam C ?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn