Garbage Collection

塵も積もれば山

目次

Blog 利用状況

ニュース

C++とかC#とか数学ネタを投下していく予定です。

[その他のページ]
日々の四方山話を綴った日記出水の日記帳

書庫

日記カテゴリ

[C][Lua]tolua++にだって…出来ないことはある…

tolua++は便利なんですが、従来のlua_Stateを受け取る形ができません。

tolua++はC言語のグルーコードを生成してくれるツールなので、
C言語で書けない形式は生成できないのです。
ですから、可変長引数、可変長返り値、型がわからない引数などは受け取れません。

int foo(lua_State *); という関数だと、自動的に見切ってくれないかな~という淡い期待は打ち砕かれ…。
ちなみに、int foo(...); という形式なら、未対応と言われて終了です。

そこで何とかしたのがこれ。

class Test{
public:
  int action1(lua_State *L);
  int action2(lua_State *L);
};

template <typename T, int (T::*F)(lua_State *) >
int glue_func(lua_State *L){
  T *self = (T *) tolua_tousertype(L,1,0);
  lua_remove(L, 1);
  int ret = (self->*F)(L);
  return ret;
}

void regist(lua_State *L){
  luaL_getmetatable(L, "Test");

  lua_pushcfunction(L, (lua_CFunction)( glue_func<Test, &Test::action1>) );
  lua_setfield(L, -2, "action1");

  lua_pushcfunction(L, (lua_CFunction)( glue_func<Test, &Test::action2>) );
  lua_setfield(L, -2, "action2");

  lua_pop(L, 1);
}

まず、tolua++で、Testのクラスだけはグルーコードを生成しておきます。
action1, action2 はluaを使って登録するので、tolua++でグルーコードは生成しません。

登録する関数は、glue_funcのテンプレートを使って、自動的にグルーコードを作ってやります。
ここで偉い人から頂いた解答をコピペしただけですけど

ただ、このコードはselfが本当にTest型なのか調べずにキャストしているので、よいコードではありません。
本来なら、tolua_isusertypeを使って、Test型なのかのチェックをするべきでしょう。

わざわざ、こんな方法を考えるきっかけは、Luaの関数型を受け取りたかったわけです。
関数型はC言語で表せないので、受け取ることはできません。

しかし、この関数型はとても便利ですので、使えないからと諦めるには惜しすぎます。
関数型をC言語で扱う方法は「[C][Lua]Luaの中の迷宮」を見てください。

投稿日時 : 2009年4月6日 3:11

Feedback

# re: [C][Lua]tolua++にだって&hellip;出来ないことはある&hellip; 2009/04/06 6:06 επιστημη

あ、ココに繋がんのね♪
そゆわけで、関数のポインタはテンプレート・パラメータ
として許されてるっす。

# re: [C][Lua]tolua++にだって&hellip;出来ないことはある&hellip; 2009/04/06 19:51 出水

ええ、ここにつながります

ポインタは型じゃなくて値だから無理だよなぁ
関数オブジェクト作るしかないのかなぁと悩んでました

あと、埋め込み文字列がテンプレートパラメータになれば
Test型のチェックルーチンも組み込めて完璧なんですけどねぇ~

タイトル
名前
Url
コメント