ホームページ > バックエンド開発 > C++ > C で void* をメンバー関数へのポインターに安全にキャストする方法

C で void* をメンバー関数へのポインターに安全にキャストする方法

Patricia Arquette
リリース: 2024-10-28 06:07:30
オリジナル
696 人が閲覧しました

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* をメンバー関数へのポインターにキャストする必要がなくなり、これら 2 つのデータ型の間でキャストする際に発生する問題が解決されます。

以上がC で void* をメンバー関数へのポインターに安全にキャストする方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート