Tolua++テクニカルドキュメント

5392 ワード

1.概要
Tolua++はプログラミング言語のテキスト変換ツールで、主にC/C++ファイルをluaに必要なインタフェース形式に変換するために使用されます.すなわち、大量の関数をstatic int XXX(lua_State*tolua_S)形式に変換し、luaに登録する.
Tolua++はpkgファイルから必要なタイプ、関数、オブジェクトをエクスポートします.
Tolua –o test.c tarray.pkg
tarray.pkgの中には対応する導出すべき内容があり、通常は対応するものが用いられる.hファイルはpkgの作成ルールで書き換えられます.生成されるtest.cプログラムにリンクし、少量のコードを追加すると、luaスクリプトでエクスポートされたクラスと関数にアクセスできます.詳しくは以下をご覧ください.http://www.codenix.com/~tolua/tolua++.html
2.実現原理
C++は関数呼び出し時にthisポインタ+関数アドレス
Luaはユーザー定義userdataを提供する
一般にluaに持つc++オブジェクトはuserdataを用いて実現される(userdataタイプは任意のCデータをLua変数に保存するために用いられる.このタイプは原生のメモリに相当し,付与値と同一性の判断を除いてLuaはそのために予め定義された操作を行わない.metatableを用いる(メタテーブル)プログラマはuserdataの操作のセットをカスタマイズすることができます.metatableでは、userdataをゴミ収集時に呼び出す関数gcを定義することもできます.
したがって、metatableはC++の関数をシミュレートし、それを置き換えることで関数、クラスメンバーの検索を実現することができます.UserdataはC++に変換するthisポインタを簡単に入手できます.このポインタ+クラスの関数アドレスでC++のクラスメンバー関数を呼び出すことができます.
3.実現
A.tolua++全体ディレクトリ構造
srcのディレクトリには
Srcbin以下はtolua++実行可能なソースコードである、主にpkgファイル生成を処理する.cファイル
Srclibはtolua++libのソースコードで、主に生成される.cファイル内の関数、クラス、オブジェクトはlua呼び出しにマッピングされます.
 
Binのディレクトリ構造
Tolua.cファイルは主にユーザのコマンドラインパラメータを受信して処理する.対応するパラメータの値をluaスタックに配置し、flagsのテーブルに格納し、luaのコードにも表示されます.マクロによるTOLUA_SCRIPT_RUNが呼び出しだと判断する
C++のコードはluaコードを呼び出します.luaコードを変更してすぐに効果を見たい場合は、このマクロを定義する必要があります.デフォルトでは、マクロは定義されていません.C++のコードがtoluabindファイルに呼び出されることを意味します.
Toluabind.cこのファイルもtolua++というツールによって生成され、srcbinluaの下のluaコードをこのcファイルに生成します.luaコードを生成する.cファイルは、主に効率のためです.Toluabind.cのコードはsrcbinluaallに対応しています.lua、主にsrcbinluaの下のluaコードをロードします.
 
Libのディレクトリ構造
Tolua_eventは主にモジュールを提供し,クラスに対応するluaメタメソッドを提供する.
Tolua_isは主にベースタイプとユーザ定義タイプのタイプ判断を提供する.
Tolua_mapの重要なクラス、モジュール、クラス、関数、メンバーの追加、クラスの継承、およびいくつかのグローバルメソッドを含む.
Tolua_pushは圧入ベースタイプを提供し、ユーザー定義タイプはluaに与える.
Tolua_toはlua内のオブジェクトからベースタイプまたはユーザ定義タイプに復元することを提供する.
 
B.エクスポートタイプ
タイプはまずtolua_と使われますusertype関数は登録され、内部ではテーブルが作成されます.
 
C.メンバー変数のエクスポート
メンバー変数は主にtolua_を通過します.variable(tolua_S,"x",tolua_get_Point_x,tolua_set_Point_x);を選択variableは、この変数のgetメソッドとsetメソッドをそれぞれ入れる.get和.seテーブルにあります.
 
D.エクスポート関数
関数はtoluaを通過します.functionはエクスポートされ、現在のモジュールテーブルまたはクラステーブルに直接配置されます.
 
E.オブジェクトのエクスポート
オブジェクトはtolua_を通過しますcclassエクスポート
TOLUA_API void tolua_cclass (lua_State*L, const char* lname, const char* name, const char* base, lua_CFunction col)
{
    …
         mapinheritance(L,name,base);継承関係を設定し、デフォルトでbaseから継承
         mapinheritance(L,cname,name);
         …
         luaL_getmetatable(L,name);
         lua_rawset(L,-3);クラスのmetatableをmoduleに設定
 
}
 
F.関連
メタテーブルを作成するとtolua_が呼び出されます.新metatableメソッド、コードは次のとおりです.
   static inttolua_newmetatable (lua_State*L, char* name)
{
         int r = luaL_newmetatable(L,name);
         …
         if (r)
                   tolua_classevents(L);/* set meta events   */
         lua_pop(L,1);
         return r;
}
tolua_が呼び出されますclassevents、この関数は現在のメタテーブルに新しい関数を登録します.
         lua_pushstring(L,"__index");
         lua_pushcfunction(L,class_index_event);
         lua_rawset(L,-3);
         lua_pushstring(L,"__newindex");
         lua_pushcfunction(L,class_newindex_event);
         lua_rawset(L,-3);
         …
 
   __index対応関数はclass_index_event、メンバーを検索するとclassにルーティングされます.index_イベントでclass_index_イベント中に向かいます.getテーブルはクエリーを行い、対応する関数があるかどうかを見て、この関数が生成されている.cファイルに登録されているので、正常にアクセスできます.
アクセス関数も同様に、
         lua_pushstring(L,"__call");
         lua_pushcfunction(L,class_call_event);
         lua_rawset(L,-3);
ルーティング先、class_call_event,,class_call_event直接調べるcallテーブルはクラスの処理関数を探します.
 
Gをまとめると,tolua++の内部は主に表構造+置換メタテーブルのメカニズムによってlua層でC++オブジェクトをシミュレートすることを実現する.
 
 
4.tolua++が提供するメカニズム
A.Tolua++はpkgファイルだけでなくluaファイルも扱うことができます.したがって、tolua++を使用する過程で、-L属性でluaコードのファイルをロードし、指定したクラスへのパッチを実現することができます.
  B.tolua++     pkg         hook,   function preparse_hook(package) lua  ,  
     http://www.codenix.com/~tolua/tolua++.html

C.tolua++は指定クラスをカスタマイズするpushusertype,isusertype,tousertype操作をサポートする
    _is_functions['Vector3'] = 'custom_is_vector3' -- checks for a 3d vector
                                               -- (either userdata, or a table with 3 values)
_to_functions['Vector3'] = 'custom_to_vector3' -- convertes the eventual table to a Vector3
 
_base_push_functions['Widget'] = 'custom_push_widget' -- pushes anything that inherits from Widget
  D.        tolua++  lua         ,    gc 。
 
5.tolua++ pkg      
    
            Package (name,fn)         ,  doit  

                push(p)
                   pre_output_hook(p)
                   pop()
p:preamble()/前置き部分の生成
p:supcode()/コード生成
                   push(p)
                   pre_register_hook(p)
                   pop()
p:register()/登録部分の生成
                  push(p)
                   post_output_hook(p)
                   pop()