LuaBridge



Luabridge



基本クラスを直接開示せず、個別に開示し、継承を宣言する基本クラス

派生クラス( 'プレーヤー')



公開されている基本クラスの直接関数はN回与えられます!!!!!階段状のピット写真!!!!!!!!!!!!




LuaBridgeの主な機能
ソースヘッダーのみ、.cppファイルなし、MakeFileなし、使用する#includeのみ。
さまざまなオブジェクトライフサイクル管理をサポートします。
簡単にアクセスできる安全なタイプ(タイプセーフ)のLuaスタック。
自動関数パラメーター型バインディング。
テーブルや関数などのLuaオブジェクトに簡単にアクセスできます。
LuaBridge APIは、のC ++テンプレートメタプログラミング(テンプレートメタプログラミング)に基づいています。これらのテンプレートは、コンパイル時にさまざまなLua API呼び出しを自動的に生成し、プログラム内のC ++クラスと関数を使用してLuaスクリプトを作成できます。数値、文字列、テーブルLua、LuaBridge LuaRefクラスを使用した簡単な呼び出し関数など、C ++でLuaデータを使用するために簡単に実行できます。
LuaBridgeの設計原則
LuaBridgeの設計目標は、ヘッダーファイルのみなど、可能な限り使いやすいため、高レベルのC ++構文を使用せず、構成を必要としません。したがって、LuaBridgeのパフォーマンスは十分ですが、OOLua(https://code.google.com/p/oolua/)の実行効率はそれよりも優れており、LuaBind(http:// www .rasterbar.com / products / luabind.html)フル機能として。 LuaBridgeは、次の機能をサポートしていません。
列挙定数
8つを超える関数またはメソッドの呼び出しはサポートされていません
オーバーロードされた関数、メソッド、およびコンストラクター(オーバーロードされた関数、メソッド、またはコンストラクター)
グローバル変数(変数は名前空間にパッケージ化する必要があります)
自動的に変換されたSTLコンテナタイプとテーブル
LuaでC ++クラスを継承します(C ++クラスからLuaクラスを継承します)。
ポインタまたは参照を期待するC ++関数にnilを渡す
std :: shared_ptrのような標準コンテナ
C ++でのLuaアクセス
LuaでC ++のデータと機能を使用するには、LuaBridgeでデータを使用する必要があります。登録する必要があります。 LuaBridgeは、次の5種類のデータを登録できます。
Luaテーブルの名前空間には追加の登録情報が含まれています
データグローバル変数または静的変数、データメンバーまたは静的データメンバー
関数一般関数、メンバー関数または静的メンバー関数
CFunctions lua_CFunction呼び出し規約を使用する通常の関数、メンバー関数、または静的メンバー関数
プロパティグローバルプロパティ、プロパティメンバー、および静的プロパティメンバー。これらはLuaにとってデータのように見えます。
ただし、値を取得および設定する関数を使用してC ++で実装されます。


プロパティとデータは、登録時に読み取り専用(読み取り専用)としてマークされます。これはconstとは異なり、これらのオブジェクトの値はC ++で変更できますが、Luaでスクリプトを変更することはできません。


名前空間
インデックスに登録されているLuaBridgeは名前空間にあり、luaの観点からは名前空間であり、本質的にテーブルです。ここで注意してください。名前空間にはC ++名前空間ではなく、C ++名前空間は必ずしも必要ではありません。名前空間は、論理結合ツール(論理グループ化ツール)として使用されるLuaスクリプトのLuaBridgeです。 Luaグローバル名前空間(グローバル名前空間)にアクセスするには、C ++で次の呼び出しを行うことができます。
int globalVar static float staticVar std::string stringProperty std::string getString () { return stringProperty } void setString (std::string s) { stringProperty = s } int foo () { return 42 } void bar (char const*) { } int cFunc (lua_State* L) { return 0 }上記の呼び出しはオブジェクト(本質的にはテーブル)を返し、次のようにさらに登録するために使用できます。
test -- a namespaceIn essence is a table, the table below are the members of test.var1 -- a lua_Number variable test.var2 -- a read-only lua_Number variable test.prop1 -- a lua_String property test.prop2 -- a read-only lua_String property test.foo -- a function returning a lua_Number test.bar -- a function taking a lua_String as a parameter test.cfunc -- a function with a variable argument list and multi-return上記の呼び出しにより、Luaの_Gに「test」というテーブルが作成されます。このテーブルは空になっています。 LuaBridgeは、すべての開始点を二重のアンダースコア名IDで保持するため、__ testは無効な名前ですが、LuaBridgeという名前はエラーではありません。上記の登録をさらに拡張できます。
test.var1 = 5 -- okay test.var2 = 6 -- error: var2 is not writable test.prop1 = 'Hello' -- okay test.prop1 = 68 -- okay, Lua converts the number to a string. test.prop2 = 'bar' -- error: prop2 is not writable test.foo () -- calls foo and discards the return value test.var1 = foo () -- calls foo and stores the result in var1 test.bar ('Employee') -- calls bar with a string test.bar (test) -- error: bar expects a string not a tableこのような登録後、Luaでtest、test.detail、およびtest.utilityを使用できます。ここで導入されたendNamespace関数は、オブジェクト(実際にはテーブルも)を返します。オブジェクトは本質的にレイヤー名前空間であり、現在の名前空間の登録が完了したことを表します。登録を作成するすべてのLuaBridge関数は、後続の登録を行うことができるオブジェクトを返し、ドット演算子を使用して無制限の数の登録を連鎖させることができます。名前空間では、LuaBridgeの同じ名前のオブジェクトの登録は未定義の動作です。名前空間を複数回使用して、メンバーを追加できます。次の例は、2つのコードに相当します。
class A { public: A() { printf('A constructor ')} static int staticData static int getStaticData() {return staticData} static float staticProperty static float getStaticProperty () { return staticProperty } static void setStaticProperty (float f) { staticProperty = f } static int staticCFunc (lua_State *L) { return 0 } std::string dataMember char dataProperty char getProperty () const { return dataProperty } void setProperty (char v) { dataProperty = v } void func1 () {printf('func1 In Class A ') } virtual void virtualFunc () {printf('virtualFunc In Class A ') } int cfunc (lua_State* L) { printf('cfunc In Class A ') return 0 } } class B : public A { public: B() { printf('B constructor ')} double dataMember2 void func1 () {printf('func1 In Class B ') } void func2 () { printf('func2 In Class B ') } void virtualFunc () {printf('virtualFunc In Class B ') } } int A::staticData = 3 float A::staticProperty = 0.5
local AClassObj = test.A () --create class A instance print('before:',test.A.staticData) -- access class A static member test.A.staticData = 8 -- modify class A static member print('after:',test.A.staticData) print('before:', test.A.getStaticProperty()) --test.A.staticProperty = 1.2 --error:can not modify print('staticCFunc') test.A.staticCFunc() AClassObj.data = 'sting' print('dataMember:',AClassObj.data) AClassObj.prop = 'a' print('property:',AClassObj.prop) AClassObj:func1() AClassObj:virtualFunc() AClassObj:cfunc() BClassObj = test.B() BClassObj:func1() BClassObj:func2() BClassObj:virtualFunc() データ、プロパティ、関数、およびCFunction
データ、プロパティ、関数、およびCFunctionは、addVariable 、、 addProperty、addFunction、およびaddCFunctionを使用して登録できます。 Luaスクリプトに関数呼び出しを登録すると、LuaBridgeは適切なパラメーター、およびパラメータータイプの転送と検査を自動的に渡します。同様に、戻り値は自動的に処理されます。現在のLuaBridgeは、最大8つのパラメーターを処理できます。パラメータとしてのクラスタイプのポインタ、参照、およびオブジェクトは特別に扱われます。 C ++で次の定義がある場合:
A constructor before: 3 after: 8 before: 0.5 staticCFunc dataMember: sting property: a func1 In Class A virtualFunc In Class A cfunc In Class A A constructor B constructor func1 In Class B func2 In Class B virtualFunc In Class B Luaでこれらの変数と関数を使用するために、次の方法でそれらを登録できます。
void useStateAndArgs (int i, std::string s, lua_State* L) getGlobalNamespace (L).addFunction ('useStateAndArgs', &useStateAndArgs)登録時の変数、2番目のパラメーターを渡すことができますfalse、Luaで変数を変更できないことを確認してください。デフォルトの2番目のパラメーターはtrueです。登録時のプロパティ、伝達関数が設定されている場合、スクリプトでは読み取り専用です。
上記を介して登録した後、Luaの次の式が有効になります。
func0 (a) -- Passes a copy of a, using A's copy constructor. func1 (a) -- Passes a pointer to a. func2 (a) -- Passes a pointer to a const a. func3 (a) -- Passes a reference to a. func4 (a) -- Passes a reference to a const a.変数を使用したC ++でのtest.prop1およびtest.prop2の参照に注意してください。その後、test.prop2は読み取り専用であるため、スクリプトでのtest.prop2の割り当てにより、ランタイムエラーが発生します(実行時エラー)。次の方法でLua:
func5 (b) - Passes a copy of b, using B's copy constructor. func6 (b) - Passes a pointer to b. func6 (a) - Error: Pointer to B expected. func1 (b) - Okay, b is a subclass of a.
クラスオブジェクト
登録はbeginClassまたはderiveClassクラスがendClass終了を開始しました。クラス登録後、beginClassの詳細情報を再登録することもできますが、deriveClassは1回しか使用できません。派生クラスクラスに登録し、より多くの情報を登録するには、beginClassを使用できます。
getGlobalNamespace (L)
次のように登録します。
 getGlobalNamespace (L) .beginNamespace ('test')
登録後、Luaスクリプトのクリックモードを使用できます。
 getGlobalNamespace (L) .beginNamespace ('test') .beginNamespace ('detail') .endNamespace () .beginNamespace ('utility') .endNamespace () .endNamespace ()

その出力は次のとおりです。
 getGlobalNamespace (L) .beginNamespace ('test') .addFunction ('foo', foo) .endNamespace () getGlobalNamespace (L) .beginNamespace ('test') .addFunction ('bar', bar) .endNamespace ()
クラス登録は通常の登録関数に類似しており、仮想関数も類似しており、特別な構文はありません。 LuaBridgeでは、constは検出メソッドの呼び出し中に識別できるため、関数がconst const Object ObjectまたはポインティングデータをLuaスクリプトに返す場合、Luaでは参照されるオブジェクトはconstと見なされ、constのみを呼び出すことができます。メソッド。クラスごとに、デストラクタが自動的に登録されます。メソッドを再登録する必要はありません。派生クラスの基本クラスに登録されています。クラスにLuaに**登録されていない**基本クラスがある場合、それをサブクラスとして宣言する必要はありません。
コンストラクター
Luaでオブジェクトクラスを作成するには、コンストラクターaddConstructorによって登録されたクラスを変更する必要があります。また、LuaBridgeがコンストラクターを自動的に検出しないパラメーターの数とタイプ(関数またはメソッドに登録されているものは自動的に検出できます)が異なるため、コンストラクター登録で使用する場合はLuaBridgeに通知する必要があります。addConstructorLuaスクリプトシグネチャを使用します。次に例を示します。
 getGlobalNamespace (L) .beginNamespace ('test') .addFunction ('foo', foo) .addFunction ('bar', bar) .endNamespace ()
Luaでは、何らかの方法でAとBのインスタンスを作成できます。
|_+_|
lua_State *
バインディング関数またはメンバー関数の場合、スタックにアクセスするためのパラメーターとしてlua_State *が必要になることがあります。 LuaBridgeを使用します。関数に最後に追加されたlua_State *タイプパラメーターがバインドされます。例えば:
 getGlobalNamespace (L)  .beginNamespace ('test') .addVariable ('var1', &globalVar) .addVariable ('var2', &staticVar, false) // read-only .addProperty ('prop1', getString, setString) .addProperty ('prop2', getString) // read only .addFunction ('foo', foo) .addFunction ('bar', bar) .addCFunction ('cfunc', cFunc)  .endNamespace () 
Luaでは、次のように使用できます。
|_+_|
スクリプトで、最初の2つのパラメーターを渡しました。関数の定義の最後までlua_State * typeパラメーターに注意してください。そうでない場合、結果は未定義です。
クラスオブジェクトタイプ
タイプTの登録、Luaスクリプトを配信するための次の可能な方法:
|_+_|
C ++の寿命
オブジェクトのC ++ライフタイム、C ++コード制御によるオブジェクトの作成と削除の場合、LuaGCはこれらのオブジェクトを再利用できません。 Lua *がlua_Stateによってオブジェクトを参照する場合、オブジェクトが削除されていないことを確認する必要があります。そうしないと、未定義の動作が発生します。たとえば、次のメソッドをLuaに渡すことができます
オブジェクトのC ++ライフタイム:
|_+_|
Luaライフタイム Lua値を介してC ++オブジェクトに渡されると、オブジェクトはLuaの有効期間になります。値が渡されると、オブジェクトはユーザーデータの形式でLua、Luaに保存され、オブジェクトへの参照がそれ以上回復できなくなった場合はGCになります。ユーザーデータが回復されると、対応するオブジェクト
デストラクタが呼び出されます。 C ++でのアプリケーションオブジェクトのLuaライフタイム。オブジェクトがGCでリカバリされていないことを確認する必要があります。そうでない場合、動作は未定義です。たとえば、次のメソッドをLuaLuaに渡すことができます。触媒の寿命は次のとおりです。
getGlobalNamespace (L)  .beginNamespace ('test')   .beginClass<A>('A')   .addConstructor <void (*) (void)> ()   .addStaticData ('staticData', &A::staticData)   .addStaticProperty ('staticProperty', &A::getStaticData)   .addStaticFunction ('getStaticProperty', &A::getStaticProperty) //read-only   .addStaticCFunction ('staticCFunc', &A::staticCFunc)   .addData ('data', &A::dataMember)   .addProperty ('prop', &A::getProperty, &A::setProperty)   .addFunction ('func1', &A::func1)   .addFunction ('virtualFunc', &A::virtualFunc)   .addCFunction ('cfunc', &A::cfunc)   .endClass ()   .deriveClass<B, A>('B')   .addConstructor <void (*) (void)> ()   .addData ('data', &B::dataMember2)   .addFunction ('func1', &B::func1)   .addFunction ('func2', &B::func2)   .endClass ()  .endNamespace ()
オブジェクトコンストラクターを作成すると、Luaに登録済みと呼ばれ、オブジェクトのLuaの有効期間は同じです。オブジェクトが参照されていない場合、GCは自動的にオブジェクトを回復します。もちろん、このオブジェクト参照をパラメーターとしてC ++に渡すこともできますが、C ++は、次の方法でオブジェクトを確実に使用する必要があることを示しています。
GCが回復されていない変更。
ポインター、参照、および値渡し
LuaのC ++コードのパラメーターとしてのC ++オブジェクトがパスから戻った場合、LuaBridge自動変換は可能な限り実行します。たとえば、次のC ++関数でLuaに登録するには:
|_+_|
次に、Luaでは、次の方法で上記の関数を呼び出すことができます。
|_+_|
上記のすべての関数には、オブジェクトのメンバーとメソッドからアクセスできます。また、C ++では、ポインターと通常の継承ルールを渡すことも使用されます。例えば:
struct A { A () } struct B { explicit B (char const* s, int nChars) } getGlobalNamespace (L) .beginNamespace ('test') .beginClass   ('A') .addConstructor <void (*) (void)> () .endClass () .beginClass   ('B') .addConstructor <void (*) (char const*, int)> () .endClass () .endNamespace ()
次の場所でluaを呼び出します:
a = test.A () -- Create a new A. b = test.B ('hello', 5) -- Create a new B. b = test.B () -- Error: expected string in argument 1
C ++ポインターがLuaNULLに渡されると、LuaBridgeは代わりに自動的にnilに変換されます。逆に、LuaをC ++に送信しない場合、C ++はNULLポインターを渡すことと同じです。
ソース:<
http://www.tuicool.com/articles/yuaqIrn >>