いまcで書かれたものをluaに書き換えようと思っています
その際にdefineで定義されたマクロ関数を書き直す際に、
luaで関数内で引数を書き換えたら実引数も書き換わるということができたらなと思いました。
やり方はありますか?
やりたいこと:
c
1#define X(x) x=0
のようなものを使いたいです
そもそも実行はluajで行うので、cのソースを呼び出すことはありません
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答1件
0
C/C++ 側の#defineやconstexprは そのまま Luaで使えないので以下のようにする必要があります
cpp
1#define MAXLENGTH 50 2const int MAXLENGTH = 50; 3constexpr int MAXLENGTH = 50; // C++11以降 4lua_pushinteger(L, MAXLENGTH); 5lua_setglobal(L, "MAXLENGTH");
上記のMAXLENGTHをLuaから参照する場合は以下のようにします。
lua
1print(MAXLENGTH)
逆に Luaのグローバル変数の値を C/C++で取得する場合は以下のようにします。
lua
1message = "ハローワールド"
cpp
1lua_getglobal(L, "message"); 2const char* message = lua_tostring(L, 1);
C/C++で定義した関数を Luaで使うには
int 関数名(lua_State* L);
のようにする必要があります。
cpp
1int add(int x, int y) { 2 return x + y; 3} 4 5int addGlue(lua_State *L) { 6 // 引数2つをスタックから取得 7 int x = luaL_checkinteger(L, 1); 8 int y = luaL_checkinteger(L, 2); 9 10 // Luaから取得した値は残ったままになっているので空っぽにする 11 lua_settop(L, 0); 12 13 // 実際の関数を実行 14 int ret = add(x, y); 15 16 // 実行した結果を Luaのスタックに戻す 17 lua_pushinteger(L, ret); 18 19 // 引数の数を返す 20 return 1; 21} 22
Luaから add関数をよびだすには lua_registerでlua_Stateを引数に持った関数を登録必要があります。
これは luaL_openlibsを実行したあとに追加します。
これを呼び出す Lua側は
lua
1print(add(10, 9))
Luaの関数を C/C++から呼び出す方法についても書いておきます。
lua
1function init() 2 return { width = 640, height = 480 } 3end
このような関数は工夫が必要となります。
cpp
1// 呼ぶ関数 2lua_getglobal(L, "init"); 3 4// 引数なし、戻り値1個として実行 5if (lua_pcall(L, 0, 1, 0) != 0) { 6 cout << "error:" << lua_tostring(L, -1) << endl; 7 return 0; 8} 9 10// テーブルの値を二つ取得 11lua_getfield(L, 1, "width"); 12lua_getfield(L, 1, "height"); 13 14// テーブルが先頭の要素を指すので2番目と3番目を取得 15int width = lua_tointeger(L, 2); 16int height = lua_tointeger(L, 3); 17 18// Luaのスタックを空っぽにしておく 19lua_settop(L, 0);
Luaのスタックを把握するために以下のような関数を作っておくと便利です。
cpp
1// スタックの指定インデックスのアイテムの内容を表示する 2static void PrintStackItem(lua_State *L, int idx) 3{ 4 int type = lua_type(L, idx); 5 switch (type) { 6 case LUA_TSTRING: 7 // 文字列アイテムの内容表示 8 printf("index %3d : type = %s\t: \"%s\"\n", 9 idx, lua_typename(L, type), lua_tostring(L, idx)); 10 break; 11 case LUA_TNUMBER: 12 // 数値アイテムの内容表示 13 printf("index %3d : type = %s : %f\n", 14 idx, lua_typename(L, type), lua_tonumber(L, idx)); 15 break; 16 case LUA_TBOOLEAN: 17 // ブール値アイテムの内容表示 18 printf("index %3d : type = %s : \"%s\"\n", 19 idx, lua_typename(L, type), lua_toboolean(L, idx) ? "true" : "false"); 20 break; 21 default: 22 // その他ならば型だけ表示 23 printf("index %3d : type = %s \n", idx, lua_typename(L, type)); 24 break; 25 } 26[リンク内容](https://github.com/ThePhD/sol2) 27} 28 29// スタックのアイテムの内容を一覧で出力する 30void PrintStack(lua_State *L) 31{ 32 printf("----- stack -----\n"); 33 int top = lua_gettop(L); 34 // 正のインデックスで指定 35 for (int i = top; i >= 1; i--) { 36 PrintStackItem(L, i); 37 } 38 printf("-------------------\n"); 39 // 負のインデックスで指定 40 for (int i = -1; i >= -top; i--) { 41 PrintStackItem(L, i); 42 } 43 printf("-------------------\n"); 44}
もう一つですが、Sol2というC++用のライブラリを使えば
例えば以下の Luaスクリプトで定義されているテーブル、グローバル変数、テーブルをいとも簡単に使えるようになっています。
lua
1-- test.lua 2function init() 3return { 4width = 640, 5height = 480 6}; 7end 8 9function initmoji() 10return { 11returnmoji = "moji" 12}; 13end
この init関数とinitmoji関数は戻り値としてテーブルを返します。このLuaスクリプトをSol2で書くと以下のように取得できます。
cpp
1#include <iostream> 2#include <sol.hpp> 3using namespace std; 4 5int main() 6{ 7 sol::state lua; 8 lua.open_libraries(sol::lib::base, sol::lib::coroutine, sol::lib::debug, sol::lib::io, sol::lib::math, 9 sol::lib::os, sol::lib::package, sol::lib::string, sol::lib::table, sol::lib::utf8); 10 11 try { 12 lua.safe_script_file("test.lua"); 13 } 14 catch (sol::error& e) { 15 cout << e.what() << endl; 16 } 17 18 // Solを使えば簡単にテーブルから値が取り出せます。 19 sol::table ret = lua["init"](); 20 cout << "width:" << ret["width"].get<int>() << endl; 21 cout << "height:" << ret["height"].get<int>() << endl; 22 23 sol::table ret2 = lua["initmoji"](); 24 cout << ret2["returnmoji"].get<std::string>() << endl; 25}
投稿2017/12/24 23:34
編集2017/12/28 05:30総合スコア178
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。