Posted at

cocos2d-x-3.0rc0 Luaバインディング(LuaからC++呼び出し)

More than 5 years have passed since last update.


はじめに

LuaとC++のバインディングは、それなりに難しい。

lua_Stack っていうのに 引数をpushしたりpopしたりして

データの受け渡ししたり

そういうあたりは、わりと 解説されているので

そちらで理解してください

勝手にリンクしてすみません 例えば

5.1さらうどん

等からリンクたどっていけば すぐわかると思います

ただ、同じように書いた場合 cocos2d-xでは 動きません

特に LuaBindingsあたり ノードキュメントなので

ソースを解析したメモ


愚直にBindingsやってみる ダメな例

定石通りに lua_open() からやってみる

(説明のため、クラスではなく 平べったい関数を登録してます)

関数は 引数なし、戻り値 文字列


AppDelegate.cpp

        // Luaエンジンを作成

auto engine = LuaEngine::getInstance();
ScriptEngineManager::getInstance()->setScriptEngine(engine);

// 定石どおり、lua_open()で lua_Stateを作成する
lua_State* L = lua_open();

// Luaから呼べる関数の登録関数
tolua_hoge_open(L);

// スクリプト実行
engine->executeScriptFile("src/main.lua");



hoge.cpp

extern "C" {

#include "tolua++.h"
#include "tolua_fix.h"
}

//GetHogeのグルーコード
int hogeGlue(lua_State *L){
const char* hoge = "test";
lua_settop(L, 0); // スタックをトップに。おまじない?
tolua_pushstring(L, hoge); //Luaスタックにhogeをpushし Luaに渡す
return 1; //返り値の数
}

TOLUA_API int tolua_hoge_open(lua_State* L){

// Luaのグローバルテーブルに hogeという関数名で hogeGlue()を登録する
lua_register(L, "hoge", hogeGlue);

return 1;
}



main.lua

    local s = hoge();

print( "s=" .. s )

実行すると、main.luaで hogeって関数がないよ!! って怒られます


なぜ見えないの?

何故見えないのか、私はこう推測しました


AppDelegate.cpp

        // ここのLuaスタックと

auto engine = LuaEngine::getInstance();
ScriptEngineManager::getInstance()->setScriptEngine(engine);

// ここのLuaスタックが違うので
lua_State* L = lua_open();

// ここでグローバルに登録したスタックは
tolua_hoge_open(L);

// 実行されるスタックとは違うのではないか?
engine->executeScriptFile("src/main.lua");



解決

lua_open()で新しい lua_Stackを作らず、おそらく ScripeEntineManagerの lua_Stackに登録すれば

いいのではないか?

ってことで、その辺りのソースを解析した結果


AppDelegate.cpp

        // ここのLuaステートを使いたい

auto engine = LuaEngine::getInstance();
ScriptEngineManager::getInstance()->setScriptEngine(engine);

// lua_open()せずに、取得関数あったよ!!
lua_State* L = LuaEngine::getInstance()->getLuaStack()->getLuaState();

// LuaEngineと同じlua_Stackに 関数登録
tolua_hoge_open(L);

//
engine->executeScriptFile("src/main.lua");


原因わかればすごい単純な事でしたが

情報がみつけられず 少し悩みました

スタックが違うんじゃないか?って想定してからは、すぐに解決しましたが

他にも悩んでいる方がいれば参考に。

もっと詳しい方、補足してくれたら嬉しい!