以前の投稿が激しく誤った情報を載せていたので修正。
Luaでクラス風のオブジェクトのメンバ関数を呼ぶ際は、 lua_pushvalue 関数を用いて、オブジェクトそのものを引数としてスタックにプッシュしてやる必要がある。
2013.11.04 昨日はそうしないとうまく動かなかった筈ですが今日やったら動きました。 lua_pushvalue でコピーしたテーブルの内容を書き換えた場合って、参照元も書き換わるのかな… よく分からんのでもし分かる人がいらっしゃったらコメントとかで教えて下さい。
main.cpp
#include <lua.hpp>
#include <stdio.h>
int main( void ) {
lua_State* L = luaL_newstate(); // Luaステートを生成
luaL_openlibs( L ); // 標準ライブラリを読み込み
// スクリプトの読み込み
if( luaL_dofile(L, "script.lua") ){
// エラー処理
printf( "%s\n", lua_tostring( L, lua_gettop(L) ) );
lua_close( L );
return 0;
}
// 犬を生成
lua_getglobal( L, "Dog" ); // グローバルなテーブル"Dog"をスタックに積む
lua_getfield( L, lua_gettop( L ), "new" ); // トップに積まれたテーブルのメンバ"new"をスタックに積む
lua_pushstring( L, "Neko" ); // 名前はNeko。犬なのにNeko。
lua_pcall( L, 1, 1, 0 ); // 実行。関数と引数はスタックから除去され、返り値が積まれる
lua_remove( L, -2 ); // 返り値の下にあるDogを除去
int idx_dog = lua_gettop( L ); // Nekoのスタック上の位置を取得
// 猫を生成
lua_getglobal( L, "Cat" ); // グローバルなテーブル"Cat"をスタックに積む
lua_getfield( L, lua_gettop( L ), "new" ); // トップに積まれたテーブルのメンバ"new"をスタックに積む
lua_pushstring( L, "Inu" ); // 名前はInu。猫なのにInu。
lua_pcall( L, 1, 1, 0 ); // 実行。関数と引数はスタックから除去され、返り値が積まれる
lua_remove( L, -2 ); // 返り値の下にあるCatを除去
int idx_cat = lua_gettop( L ); // Inuのスタック上の位置を取得
printf( "%d object\n", lua_gettop( L ) ); // スタックのサイズが正しい事を確認
// メンバ関数showを呼び出し
lua_getfield( L, idx_dog, "show" ); // 関数をスタック
printf( "%d object and function\n", lua_gettop( L ) );
lua_pushvalue( L, idx_dog ); // 引数selfをスタック
printf( "%d object, function, and argument\n", lua_gettop( L ) );
// 実行
if( lua_pcall( L, 1, 0, 0 ) ){
// エラー出力
printf( "%s\n", lua_tostring( L, lua_gettop( L ) ) );
}
printf( "%d objects\n", lua_gettop( L ) );
// メンバ関数showを呼び出し
lua_getfield( L, idx_cat, "show" ); // 関数をスタック
printf( "%d object and function\n", lua_gettop( L ) );
lua_pushvalue( L, idx_cat ); // 引数selfをスタック
printf( "%d object, function, and argument\n", lua_gettop( L ) );
// 実行
if( lua_pcall( L, 1, 0, 0 ) ){
// エラー出力
printf( "%s\n", lua_tostring( L, lua_gettop( L ) ) );
}
printf( "%d object\n", lua_gettop( L ) );
lua_close( L ); // 終了
return 0;
}
script.lua
-- Dog
Dog = {}
Dog.new = function( name )
local obj = {}
obj.name = name
obj.show = function( self )
s = string.format( "%s the DOG.", self.name )
print( s )
end
return obj
end
-- Cat
Cat = {}
Cat.new = function( name )
local obj = {}
obj.name = name
obj.show = function( self )
s = string.format( "%s the CAT.", self.name )
print( s )
end
return obj
end
0 件のコメント:
コメントを投稿