この第一版は、Lua 5.0用に書かれました。後のバージョンでも多くは関連していますが、いくつかの違いがあります。
第四版はLua 5.3を対象にしているもので、Amazonおよび他の書店で手に入れることができます。
書籍を購入することで、Luaプロジェクトのサポートにも協力できます。


28.5 – ライトユーザーデータ

ここまで使用してきたユーザーデータのことをフルユーザーデータと呼びます。Luaは、ライトユーザーデータと呼ばれるもう1つの種類のユーザーデータを提供します。

ライトユーザーデータは、Cポインターを表す値(void *値)です。これは値なので、作成しません(数値を作成しないのと同様)。ライトユーザーデータをスタックに追加するには、lua_pushlightuserdataを使用します。

    void lua_pushlightuserdata (lua_State *L, void *p);

ライトユーザーデータは名前が似ていますが、フルユーザーデータとは大きく異なります。ライトユーザーデータはバッファーではなく、単一のポインターです。メタテーブルはありません。ライトユーザーデータは数値と同様に、(必要ないので)ガーベージコレクターで管理する必要がありません。

ライトユーザーデータをフルユーザーデータの安価な代替として使用している人もいますが、これは一般的な使用方法ではありません。まず、ライトユーザーデータでは、ガーベージコレクションの対象ではないため、メモリを自分で管理しなければなりません。次に、名前とは裏腹に、フルユーザーデータも安価です。指定したメモリサイズに対するmallocと比較すると、オーバーヘッドはほとんどありません。

ライトユーザーデータの真の用途は、等価性にあります。フルユーザーデータはオブジェクトであるため、自分自身としか等しくありません。一方、ライトユーザーデータはCポインター値を表します。それ自体と同じポインターを表す全ユーザーデータと等しくなります。したがって、ライトユーザーデータを使用して、Lua内のCオブジェクトを見つけることができます。

典型的な例として、Luaとウインドウシステム間のバインディングを実装する場合を考えてみます。このバインディングでは、フルユーザーデータを使用してウインドウを表わします。(各ユーザーデータには、ウインドウ構造全体が含まれている場合も、システムによって作成されたウインドウへのポインターのみが含まれている場合もあります。)ウインドウ内でイベントが発生した場合(例: マウスクリック)、システムは特定のコールバックを呼び出し、アドレスによってウインドウを特定します。コールバックをLuaに渡すには、特定のウインドウを表すユーザーデータを見つける必要があります。このユーザーデータを見つけるには、インデックスがウインドウアドレスのライトユーザーデータで、値がLuaのウインドウを表すフルユーザーデータのテーブルを保持します。ウインドウアドレスを取得したら、それをAPIスタックにライトユーザーデータとしてプッシュし、そのユーザーデータをそのテーブル内のインデックスとして使用します。(そのテーブルには弱い値が含まれている必要があることに注意してください。そうしないと、それらのフルユーザーデータは決して収集されません。)