エクスポートC/C++APIはLuaに使用されます.

11318 ワード

エクスポートC/C++APIはLuaに使用されます.
 
cocococos 2 d-xとquick-cocococococos 2 d-xの下のコードはいずれもC++言語を使って開発されています.Luaスクリプト言語を使って開発するために、私達は利用します.  tolua++ ツールは、大量のC/C++APIをLuaにエクスポートします.
tolua++を使用する基本的な手順:
  • C/C++ソースコードからヘッダファイルの内容をコピーします.toluaファイルにあります.
  • 修正.toluaファイルの内容、tolua++では認識できない内容を削除し、Luaの定義にエクスポートする必要がありません.
  • は、tolua++ツールを実行し、toluaファイルからlubindingインターフェースファイルを生成する(.cppファイルと.hファイルを自称する).
  • は、AppDelegate.cppにlubindingファイルをロードする.
  • AppDelegateでLua仮想マシンを初期化した後、luabiindingインターフェースファイルのluaopen関数を呼び出して、C/C++APIを登録します.
  • 実践によって、私たちは次のような方案を採用して全体の導出作業を完成することを提案します.
     
    C/C++ソースファイルから作成.toluaファイル
    私たちの MyClass.h ヘッダファイルの内容は以下の通りです.
    #ifndef __MY_CLASS_H_
    #define __MY_CLASS_H_
    
    class MyClass {
    public:
        static void addTwoNumber(float number1, float number2);
    
    private:
        MyClass(void) {}
    };
    
    #endif // __MY_CLASS_H_
    メンテナンスを容易にするために、hファイル対応のtoluaをXXX_と名づけるべきです.luabiinding.tolua.このように生成されたluabiindingインターフェースのファイル名はXXX_です.luabinding.cppとXXX_luabinding.hは既存のC/C++ソースファイルと競合しません.
    MyClass_を作成しますluabinding.toluaファイルで、修正内容は:
    class MyClass : public CCObject
    {
    public:
        static void addTwoNumber(float number1, float number2);
    };
    ここで見ることができます.toluaの内容は明らかに簡略化されています.詳しい内容は規則を改正して、本文の後の部分で説明します.
     
    luabiindingインターフェースファイルを生成します.
    この作業を簡略化するために、該当ツールを提供します.シナリオファイルを作成してツールを呼び出すだけでいいです.
  • build_を作成します.luabiinding.shファイルの内容は以下の通りです.
    #!/usr/bin/env bash
    DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
    cd "$DIR"
    OUTPUT_DIR="$DIR"
    MAKE_LUABINDING="$QUICK_COCOS2DX_ROOT"/bin/compile_luabinding.sh
    $MAKE_LUABINDING -E MyClass -d "$OUTPUT_DIR" MyClass_luabinding.tolua
    はコマンドラインのchmod 755 build_を覚えています.luabinding.shでなければ、スクリプトは実行できません.Windows版のバッチの処理内容は以下の通りです.
    @echo off
    set DIR=%~dp0
    set OUTPUT_DIR=%DIR%
    set MAKE_LUABINDING="%QUICK_COCOS2DX_ROOT%\bin\compile_luabinding.bat"
    pushd
    cd /d "%DIR%"
    call %MAKE_LUABINDING% -E MyClass -d %OUTPUT_DIR% MyClass_luabinding.tolua
    注意:シナリオを実行する前に、QUICK-cococococococos 2 d-xがダウンロードされていることを確認してください.QUICK_が正しく設定されています.COCOCOCOCOCOS 2 DX_ROOT環境変数.環境設定は「入門ガイド」を参照してください.
  • コマンドラインで作成したスクリプトを実行します.うまくいけば、次のような出力情報が見られます.
    creating file: MyClass_luabinding.cpp
    creating file: MyClass_luabinding.h
    
    // add to AppDelegate.cpp
    #include "MyClass_luabinding.h"
    
    // add to AppDelegate::applicationDidFinishLaunching()
    CCLuaStack* stack = CCScriptEngineManager::sharedManager() ->getScriptEngine() ->getLuaStack();
    lua_State* L = stack->getLuaState();
    luaopen_MyClass_luabinding(L);
    
  •  
    lubindingインターフェースファイルをロードする
    私達のプロジェクトを開けて、MyClass_を作ります.luabinding.cppとMyClass_luabinding.hファイルはプロジェクトに参加します.そしてAppDelegate.cppファイルを修正します.
  • AppDelegate.cppヘッダ領域に追加する:
    #include "MyClass_luabinding.h"
  • AppDelegate:appection DidFinish Launching関数に追加する:
    luaopen_MyClass_luabinding(L);
    この行のコードは他のluaopen関数の後に追加するべきであることに注意してください.例えば、
    // register lua engine
    CCLuaEngine *pEngine = CCLuaEngine::defaultEngine();
    CCScriptEngineManager::sharedManager()->setScriptEngine(pEngine);
    
    CCLuaStack *pStack = pEngine->getLuaStack();
    lua_State* L = pStack->getLuaState();
    
    // load lua extensions
    luaopen_lua_extensions(L);
    // load cocos2dx_extra luabinding
    luaopen_cocos2dx_extra_luabinding(L);
    
    // thrid_party
    luaopen_third_party_luabinding(L);
    
    // CCBReader
    tolua_extensions_ccb_open(L);
    
    // MyClass
    luaopen_MyClass_luabinding(L);
    は私達のコードをtolua_に追加するべきです.extensionscccopen()の後ろ
  • 上記の修正を経て、運行項目を再コンパイルすれば、Luaスクリプトで私達が導出したMyClassオブジェクトを使用することができると思います.
     
    .toluaファイルの内容の修正規則
    前のMyClassは非常に簡単な例ですが、実際にゲーム中のC/C+APIは複雑かもしれません.Toluaファイルの内容を修正する時は、以下の内容をよく読むべきです.
     
    Luaで使用する必要のないすべての内容を削除します.
    エクスポートされたAPIが多いほど、Lua仮想マシンで占有されるシンボルテーブル空間が多くなります.そこで、私たちが最初にやるべきことは、Luaで使う必要のないすべての内容を削除することです.
  • は、enum、マクロの定義について、導出が必要ならば、原文は保留すれば良い.しかし、マクロ定義は、数値定義のみを導き出すことができます.例えば、
    #define kCCHTTPRequestMethodGET 0
    #define kCCHTTPRequestMethodPOST 1
    ではなく、マクロ定義は導き出せません.以下の内容は失敗を導き出すことができます.
  • は、CC_など、識別できないすべてのマクロを削除する.DLL
  • C++クラスのすべての非publicの定義を削除します.
  • は、C++クラスのクラスメンバー変数を削除します.
  • inlineのキーワードを削除するだけでなく、inline functionの実装は、ステートメントを保持します.
  •  
    CCObjectの後継クラスを処理します.
    CCObjectとその後継クラスはいずれも「参照カウント」と「自動リリース」の機構を備えています.もしあなたのC++の対象がCCObjectから継承されるなら、tolua++に対応する処理をしてください.そうでないとメモリ漏れなどの問題が発生する可能性があります.
    quickについては、buildスクリプトで-E CCOBJECTSパラメータでこれらのクラスの名前を指定すればいいです.
    例えば、以前のMyClassの例では、−E CCOBJECTS=MyClassでtolua++はMyClassをCCObjectの後継クラスとして扱うべきだと教えられている.
    複数のクラスがある場合は、各クラス名の間を「,」で区切ればいいです.
    #define kMyConstantString "HELLO"
     
    マクロを展開
    マクロの中には、CC_などの直接的な削除はできません.PROPRERTY.このようなマクロについては、マクロ定義に基づいて、宣言としてマクロを展開する必要があります.
    $MAKE_LUABINDING -E CCOBJECTS=MyClass,MyClass2,MyClass3 -d "$OUTPUT_DIR" MyClass_luabinding.tolua
    
    展開:
    CC_PROPERTY(float, m_fDuration, Duration)
    このような処理が必要なマクロは、CC_を含む.PROPRERTY_READONLY,CC_PROPRERTY,CC_PROPRERTY_PASS_BY_REF,CC_SYNTHESIZE_READONLY,CC_SYNTHESIZE_READONLY_PASS_BY_REF,CC_SYNTHESIZE,CC_SYNTHESIZE_PASS_BY_REF,CC_SYNTHESIZE_RETAINです
    幸いなことに、これらのマクロはcococos 2 d-xベースコードだけで使われることが多いです.私たち自身のC++classはこれらのマクロを使わないようにします.
     
    名前空間の処理
    名前空間を使うなら、トーラの頭に入れるべきです.
    float getDuration();
    void setDuration(float v);
    ここで使っている「$」の記号は、その後の内容をそのままlubindingファイルに入れます.
     
    必要なÜincludeコマンドを追加します.
    生成されたlubindingインターフェースファイルがコンパイルできない場合は、include対応のヘッダファイルが必要かどうかを確認し、次のコードを追加します.
    $using namespace myname;
     
    関数のパラメータと戻り値の種類を変更し、const修飾子を削除します.
    いくつかの関数のパラメータまたは戻り値は、const修飾子を使用しています.tolua++の制限のため、このような定義をうまく処理できません.だから、私たちはtoluaファイルからconst修飾子を削除します.唯一の例外はconst char*をchar*に変更する必要はありません.
    たとえば:
    $#include "MyClass.h"
    変更するべきです
    CCPoint convertToNodeSpace(const CCPoint& worldPoint);
    このように修正された理由は、tolua++は、const CCPointとCCPointを2つの異なるタイプとして扱うためである.変更しないと、関数を呼び出したときにパラメータの種類が一致しないと報告されます.
     
    C/C++関数から複数の値を返します.
    関数のすべてのパラメータが参照またはポインタタイプであり、const char*ではない場合、lubindingインターフェースファイルでは、関数は複数の値を返します.
    たとえば:
    CCPoint convertToNodeSpace(CCPoint& worldPoint);
    Luaでこの関数を呼び出すと、2つの戻り値が得られます.
    void getPosition(float* x = 0, float* y = 0);
     
    Lua関数をC/C++に入力します.
    quickでは、Lua関数をC/C++に導入することができます.C/C++関数でintを使用してパラメータタイプを作成します.しかし.toluaファイルにはLUA_を使用しなければならない.FUNTIONはパラメータタイプをします.
    たとえば:
    local x, y = node:getPosition()
    listenerパラメータは、入力されたLua関数を保存するために使用されます.したがって、toluaファイルでは、次のように書き換えられます.
    static CCHTTPRequest* createWithUrlLua(int listener,
            const char* url,
            int method = kCCHTTPRequestMethodGET);
    具体的な使い方はlib/cococos 2 dx_を参照してください.extra/extra/network/CCHT TPrequestにおけるcreateWithUrlLua()の方法.
     
    LuaとC/C++間でバイナリデータを交換します.
    C/C++からバイナリデータをLuaに返すには、関数の戻り値タイプはintでなければなりません.toluaファイルでは戻り値をLUA_に変更します.STRING.関数では、CCLual Stock:pusshString()でLual stackにバイナリデータを入れる必要があります.その後、「Luaに渡す必要がある値」の数を返します.
    具体的な使い方はlib/cococos 2 dx_を参照してください.extra/extra/network/CCHTTPRequestにおけるgets ResonseDataLua()方法.
    LuaからバイナリデータをC/C++に渡すのは簡単で、const char*パラメータタイプとintタイプパラメータを使って、バイナリデータのポインタとデータ長をそれぞれ指定します.
    具体的な使い方はlib/cococos 2 dx_を参照してください.extra/extra/crypt/CCCryptの中のdecrypt XTEALuaの方法です.
     
    もっと多くの使い方
    tolua++を利用するもっと多い使い方については、lib/cococos 2 dx_を参考にしてください.extraの中のCCCrypt、CCNative、CCHTTPRquestなどのクラスです.これらのclassはLuaに対して良好な支持を提供しています.具体的な使い方はほとんどのC/C++とLua相互作用の需要をカバーしています.
    -END-