luaにカスタマイズのc++クラスを使う

cocos2d-xのライブラリにカスタマイズのc++クラスを追加し、luaから呼び出せる方法です。
環境はcocos2d-x 3.15 + Xcode v8.3.2 + macOS Sierra v10.12.4です。注1

  1. クラスを作成

    1. プロジェクトルート/frameworks/cocos2d-x/cocos/の下にcustom(任意)というフォルダを作成
    2. customの下にc++のクラスGameData(任意)を作成
    3. Xcodeでプロジェクトを開き、追加したクラス(フォルダごと)をcocos2d_libs.xcodeprojの直下に追加
  2. binding用設定ファイルを作成

    1. プロジェクトルート/frameworks/cocos2d-x/tools/tolua/の下にある比較的簡単な設定ファイルcocos2dx_csloader.iniをコピーしてcustom_game_data.iniにリネーム
    2. custom_cpp.iniを開き、下記のように変更を加え
      • genbinding.pyに使う名前を変更
        [cocos2dx_csloader] を
        [custom_game_data] に変更
      • 自動生成されるc++ブリッジ関数の接頭語
        prefix = cocos2dx_csloader を
        prefix = custom_game_data に変更
      • lua用のモジュール接頭語(ネームスペースと似たもの)
        target_namespace = cc を
        target_namespace = に変更(ネームスペースが必要なければccを削除 ※注2)
      • 生成したc++クラスのヘッダー位置
        headers = %(cocosdir)s/cocos/editor-support/cocostudio/ActionTimeline/CSLoader.h を
        headers = %(cocosdir)s/cocos/custom/GameData.h に変更
      • luaで使うためのクラスですので、スキップする関数はないはず。
        skip = CSLoader::[nodeFromXML nodeFromProtocolBuffers createTimeline nodeWithFlatBuffers createActionTimelineNode createNodeWithDataBuffer createTimelineWithDataBuffer ^createNode$] を
        skip = に変更
    3. プロジェクトルート/frameworks/cocos2d-x/tools/tolua/genbindings.pyを開き、141行あたりにあるcmd_argsキーの最後に上記のcustom_game_data.iniを追加
      ‘custom_game_data.ini’ : (‘custom_game_data’, ‘lua_custom_game_data_auto’), \
      ※もし2番めのパラメーター’custom_game_data’がiniファイル1行目に定義された名前と一致しなければ、Section not found in config file的なエラーができます。
    4. 以下のようにgenbindings.pyを実行してc++のブリッジクラスを生成
      python genbindings.py
      ※ImportError: No module named yamlというようなエラーが出た場合、genbindings.pyと同ディレクトリにあるREADMEを参考にして、以下のコマンドで必要なモジュールをインストール

      • sudo easy_install pip
      • sudo pip install PyYAML
      • sudo pip install Cheetah


      こうすれば、プロジェクトルート/frameworks/cocos2d-x/cocos/scripting/lua-bindings/auto/の下に、lua_custom_game_data_auto.hppとlua_custom_game_data_auto.cppが生成されます。
      c++クラスの関数名変更するたびに、このステップを再実行する必要があります。

  3. 生成されたファイルをプロジェクトに追加

    1. 自動生成されたlua_custom_game_data_auto.hppとlua_custom_game_data_auto.cppをXcodeのプロジェクトのcocos2d_lua_bindings.xcodeproj/autoの直下に追加
    2. cocos2d_lua_bindings.xcodeproj/CCLuaStack.cppに今回追加したクラスへの参照を追加
      #include "scripting/lua-bindings/auto/lua_custom_game_data_auto.hpp"
      同ファイルのbool LuaStack::init(void)関数に新しいクラスを登録
      register_all_custom_game_data(_state);
    3. Android向けに、プロジェクトルート/frameworks/cocos2d-x/cocos/scripting/lua-bindings/proj.android/Android.mkの140行あたりに以下のようにソースファイル参照を追加
      LOCAL_SRC_FILES += ../../../custom/GameData.cpp \
        ../auto/lua_custom_game_data_auto.cpp \
  4. リビルド

    1. プロジェクトをリビルドすれば、luaで以下のように使えるはずです。
      local gameData = GameData:new()
      gameData:getName() --仮にgetName()を実装したとして

※注1: 現時点Xcode8以上のバージョンだと、luaのプロジェクトはiOSシミュレーター上で動きません。
Xcode7以前のバージョンを使うか、iPhone実機もしくはmac(***-desktopプロジェクト)でデバッグ必要があります。
参考:https://github.com/cocos2d/cocos2d-x/issues/17043

2017/05/29追記:上記ページに紹介されたように、luajitをアップデートすれば実行できます。
具体的には、https://github.com/cocos2d/cocos2d-x-3rd-party-libs-bin/blob/v3/lua/luajit/prebuilt/ios/libluajit.aをダウンロードして、プロジェクトルート/frameworks/cocos2d-x/external/lua/luajit/prebuilt/ios/libluajit.aと置き換えれば良いです。

※注2: target_namespaceを指定すれば、ネームスペースをppと仮定して下記の作業が必要になります。

  1. custom_game_data.iniにcpp_namespace = ppを追加
    ※そうしなければ、クラスに定義した関数にもかかわらず、CCLuaStack.cpp: error: undefined reference to的なエラーが出ます。
  2. プロジェクトルート/frameworks/cocos2d-x/tools/bindings-generator/targets/lua/conversions.yamlの20行あたりにあるns_map:のキーの一番最後に
    "pp::": "pp."
    を追加
    ※そうしなければ、The namespace (%s) conversion wasn’t set in ‘ns_map’ section of the conversions.yaml” % namespace_class_nameというようなエラーができます。

参考

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください