1 名前:デフォルトの名無しさん mailto:sage [2009/05/25(月) 09:11:41 ] LuaやSquirrelなどアプリケーションへの組み込み用途で 使われるプログラミング言語についてのスレッドです まとめwiki(なにか質問する前に必ずみること!) wikiwiki.jp/lua/ その他の参考URLは>2から ■前スレ 【Lua】組み込み系言語総合【Squirrel】 pc12.2ch.net/test/read.cgi/tech/1205208141/ ■過去スレ その3 pc11.2ch.net/test/read.cgi/tech/1160799232/ その2 pc8.2ch.net/test/read.cgi/tech/1063711237/ その1 pc5.2ch.net/tech/kako/1034/10341/1034182349.html
39 名前:デフォルトの名無しさん mailto:sage [2009/06/05(金) 13:47:55 ] >>37 あれ? すると、ちょっと解せない動作があるな。 C++側で定義したPointクラスをSquirrelにバインドしているんだが このインスタンスに対する加算を function Point::_add(point) の形でSquirrelスクリプトの中で追加登録している。 この状態でインスタンスに対して加算を行われると、いったんSqBindのgetterを呼び出して失敗してから _addが呼ばれているように見えるんだな。 メタメソッドは元から通常のメンバ・メソッドとは違う扱いになっているからそれでかなぁ。 # 例えばインスタンスに対してforeachをかけても登録したメタメソッドを検出できない。
40 名前:デフォルトの名無しさん mailto:sage [2009/06/05(金) 15:34:28 ] >>39 あー、なんかわかった。俺の理解はおかしかった >あと、メタメソッドは機構上、必ずインスタンスに張り付いてるそれが呼び出されるようで、 >メタメソッドを上書きしてから親クラスのそれをよびだそうとしても自分のそれが >呼び出されて無限ループになるって罠もあったり <はまった これ間違い メタメソッドは登録時に特殊処理されてて、クラスオブジェクト内の専用のテーブルに格納されてて、 メソッドとしてそもそも生えてない模様。 (class オブジェクトの _metamethods につっこまれてる) クラスオブジェクトにメソッドが生えてないから、当然インスタンス側にもコピーされてきてない。 インスタンスでのメタメソッド呼び出し処理は、VM内から直接クラスオブジェクト内の _metamethods を見に行ってる こんなかんじで呼び出そうとしてたんだけど(ちょっとうろおぼえコード) function _get(name) { if (自前処理) { return XXX; } else { // みつからないので親に投げる return Parent::_get(name); } } 1. Parent::_get はそもそも存在してない(メタメソッドなのでクラスにも生えてない) 2. Parent::hoge のようなクラスメソッド呼び出しは、VM側がコンテキストをすり替えて this コンテキストで呼び出し開始されてる 3. 存在してないから今のコンテキストの _get が "_get" を探すために呼び出し開始される 4. 無限ループ こんなオチではないかと そちらのほうだと、Point::_add() をよびだそうとした時点で同じことがおこってるんじゃないかな。たぶん。 その先がちょっとわからんのだけど、もしかしたら SqBind がさらにテーブルから検索して呼び出すとか そういう処理が入ってたりするのかな? どちらにしても大変気持ち悪いことになってるってことになるんじゃないかと…
41 名前:デフォルトの名無しさん mailto:sage [2009/06/05(金) 15:57:59 ] >>40 スクリプト言語的にはメタメソッドも通常のメンバのように見えているべきなんだけど、 おそらく動作効率上の問題でそうなっているんだろうね。 メタメソッドの存在チェックはAPIが存在しないかもしれない。 Sqratがちょうどそんな実装で、バインドしたメンバの一覧に_getで呼び出されたメンバ名が存在しない場合、 エラーを返さずに何もしないものだから、 Squirrelインタプリタは返ってきたnullに対してメタメソッドの呼び出しをかけようとして失敗してる、んだったかな。 とにかくバインダ側で登録する_getは、管轄外メタメソッド呼び出しに対してはfalseまたは例外を返してあげないといけない。 Squirrelインタプリタの実装側ももうちょっとやりようがありそうな気がするけどね。
42 名前:デフォルトの名無しさん mailto:sage [2009/06/10(水) 14:06:39 ] androidでlua使える code.google.com/p/android-scripting/
43 名前:デフォルトの名無しさん mailto:sage [2009/06/11(木) 00:03:37 ] 久しぶりにRSS更新キターと思ったらそのニュースでちょとガッカリ。
44 名前:デフォルトの名無しさん mailto:sage [2009/06/11(木) 00:14:17 ] Google AndroidはカスタマイズされたLinuxそのものなんだから、 元から使えて当たり前だもんなぁ。
45 名前:デフォルトの名無しさん mailto:sage [2009/06/11(木) 04:03:51 ] Cにさ、lua 組み込んでるとさ、luaのソースみたときに、どの識別子が Cから参照されていて、どれがローカルだけで使用されているのかわからなくなる場合があるよね。 命名規則とか、やってる? 一応、Cから呼ばれる関数と変数名は全て __ で始まるようにしてる。 でも大文字で始まっているのが全てCから参照される識別子 って規則の方がほうが わかりやすいのかな。どうだろう。 __ で始まるのは、間違いが無い気がする。 大文字で始める識別子って、けっこううっかりつけそうな気がする
46 名前:デフォルトの名無しさん mailto:sage [2009/06/11(木) 08:39:16 ] >>45 local宣言しないとローカルにならないし requireもあるから問題無いよ
47 名前:デフォルトの名無しさん mailto:sage [2009/06/11(木) 13:06:52 ] >>46 それでは45に対する答えになってないだろ。 答えは、「区別する必要はない」だな。 後始末が必要ならファイナライザでも書いてあげれば済むことだ。
48 名前:デフォルトの名無しさん mailto:sage [2009/06/11(木) 23:07:53 ] 馬鹿っぽいこときくかも知れないけど C言語レベルのプリプロセッサのライブラリってあるの? 軽量スクリプト言語の、さらに前処理用。 自作しろといわれりゃ相応の時間をかければ作れそうだけど、 こういう泥臭いのは必要な人は自分で作るのかなあ。
49 名前:デフォルトの名無しさん mailto:sage [2009/06/11(木) 23:18:36 ] >>48 CPP32ってC/C++プリプロセッサがVectorにあるよ。 あとboost::waveとか。
50 名前:デフォルトの名無しさん mailto:sage [2009/06/11(木) 23:22:52 ] ttp://spirit.sourceforge.net/repository/applications/wave.html このへん? ライセンスは boost
51 名前:48 mailto:sage [2009/06/11(木) 23:33:12 ] どうもありがとう。見てみます
52 名前:デフォルトの名無しさん mailto:sage [2009/06/12(金) 03:19:25 ] プリプロセッサはなぁ……。 有用さは認めるし、実際プリプロセッサを活用したゲームの処理系は見たことあるわけだが、 結局ソースコードが爆発してコンパイラ・インタプリタ側に負担がかかるのが落ちなので、 オレはあまり賛成はしかねる。 C++とC#のビルド速度の差を思うとな。
53 名前:デフォルトの名無しさん mailto:sage [2009/06/12(金) 10:40:09 ] あらかじめプリプロセッサを通してスクリプトを変換し、それをプログラムに読み込ませるという手もあるよ。 ただ、Luaでそれやるとコンパイルエラー出まくりだったと思う。 AngelScriptは問題なし、Squirrelもたぶん問題ないと思う。 ただ、外部スクリプトであったらいいなと思うプリプロセッサの機能は#includeだけのような気がする。
54 名前:デフォルトの名無しさん mailto:sage [2009/06/12(金) 19:42:57 ] lua でソース分割したいとき(というよりも、ソースを複数のluaスクリプトで共有したいとき) ってどうすればいいの? Luaファイルをロードしてライブラリとして登録みたいな関数がある?
55 名前:デフォルトの名無しさん mailto:sage [2009/06/13(土) 01:09:49 ] マクロプロセッサといえばm4 >>54 requireかdofileじゃだめ?
56 名前:デフォルトの名無しさん mailto:sage [2009/06/15(月) 19:46:26 ] Luaに名前空間ってあるんですか? 同名関数が別ファイルにあったばあいどうするんですか?
57 名前:デフォルトの名無しさん mailto:sage [2009/06/15(月) 21:48:03 ] あまりに糞なライブラリなら捨てて再構築するのもいいんじゃないか。 軽量スクリプト言語なんだし
58 名前:デフォルトの名無しさん mailto:sage [2009/06/15(月) 22:05:45 ] >>56 グローバル変数を参照または代入する際に呼ばれるメタメソッドを設定できるよ
59 名前:デフォルトの名無しさん mailto:sage [2009/06/16(火) 19:09:48 ] >>58 同名関数が有った場合の挙動の設定ができる、 という意味でしょうか。 同名関数のあるLuaファイル2つを C++側で開いた時、どうしても呼び分けられない・・・・
60 名前:デフォルトの名無しさん mailto:sage [2009/06/16(火) 20:21:26 ] >>59 というか、LuaもSquirrelも関数はファーストクラスオブジェクトなんだから、 2回定義したら最初のやつは消えちゃうでしょ? オーバーロードとかはそのままではできんわなー
61 名前:デフォルトの名無しさん mailto:sage [2009/06/16(火) 20:28:08 ] >>56 テーブルで名前空間っぽいものが実現できる。 -- A.lua A = {} function A.hoge() ... end みたいに書いてCからは lua_getglobal(L, "A"); lua_getfield(L, "hoge"); lua_call(L, 0, 0); で呼び出せる。
62 名前:デフォルトの名無しさん mailto:sage [2009/06/16(火) 23:17:00 ] >>60-61 ありがとうございます! 成功しました!
63 名前:デフォルトの名無しさん mailto:sage [2009/06/24(水) 09:22:21 ] LuaってluaL_loadbufferして lua_pcallしたあと、 luaL_loadbufferのバッファって捨てられないんかな? loadbufferしてpcallすると 実際のバイナリサイズの二倍くらいメモリを食っているようなんで pcall後のloadbufferのチャンクは 感覚的にはいらないように感じるんだけど……。
64 名前:デフォルトの名無しさん mailto:sage [2009/06/25(木) 00:55:31 ] lua 5.1.4 を Mac OS X 10.5.7 で動かしてるのですが、バイナリモードでファイル書き込みが出来ません。 v = 1 fh = io.open("samplefile", "wb") if fh ~= nil then fh:write(v) fh:close() end を実行すると、samplefileの中身は0x01では無く0x31です。 バイナリモードの書き込みはどうすればいいのかご存知の方教えて下さい。
65 名前:デフォルトの名無しさん mailto:sage [2009/06/25(木) 11:58:28 ] >>64 v = "\1"
66 名前:デフォルトの名無しさん mailto:sage [2009/06/25(木) 12:01:56 ] C# にIronPythonを組み込んで色々といじってみてるところなんだが、 C#のクラスをPython側で使うときの便利さが神すぎるな。 なんせ、バインダ用のコードなんて一行も書く必要なく、 Python側で通常のモジュールのようにimportするだけで普通に作ったり殺したりできるんだから。 (当然ながら触れるのはC#側でpublicに指定している部分のみ) いやはや。.NET Frameworkはすばらしい。 反面、Python側のコードをC#側から呼び出すのはちょっとしたおまじないが必要だが、 これはまあ型のある言語から型の無い言語の機能を呼び出すのに手間がかかるのはしょうがないかなぁ。
67 名前:デフォルトの名無しさん mailto:sage [2009/06/25(木) 12:13:04 ] 64です。 liolib.cをみたら、g_write()の中で if (lua_type(L, arg) == LUA_TNUMBER) { /* optimization: could be done exactly as for strings */ status = status && fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0; } な事してるので文字にしちゃうんですね。バイナリで書き出すのはやめときます。
68 名前:デフォルトの名無しさん mailto:sage [2009/06/25(木) 12:15:48 ] >>65 ありがとうございます。なるほど、たしかにそれだと0x01が書き出されました。
69 名前:デフォルトの名無しさん mailto:sage [2009/06/25(木) 12:18:33 ] >>67 ファイルIOくらい、簡単に自作してしまえばどう? Squirrelの標準ライブラリはバイナリファイルしかろくに読めない代物なので、 通常の読み書きは自作のクラスを使ってるよ。 C/C++で書いてバインドしてしまえばいい。
70 名前:デフォルトの名無しさん mailto:sage [2009/06/25(木) 13:18:56 ] >>69 64です。 そうですね、頑張ってみる事にします。 まだlua始めて間もないので、もう少し慣れてからですかね。 アドバイスありがとうございます。
71 名前:デフォルトの名無しさん mailto:sage [2009/06/26(金) 06:38:29 ] >>66 .netのいいところは、同じ.netの言語の相互運用が従来の組み込み言語より格段に楽なところだよなー。 俺が何をいいたいかというと、IronRuby頑張ってくれっていう
72 名前:デフォルトの名無しさん mailto:sage [2009/06/26(金) 09:28:58 ] Google V8を組み込み言語として使ってみた人いる? 速度的にはどんなもん?
73 名前:デフォルトの名無しさん mailto:sage [2009/06/26(金) 14:25:35 ] うは。IronPythonのスクリプトをアセンブリ(DLL)にコンパイルして、普通に実行できてしまった。 すごすぎるwww まあ逆コンパイルして眺めてみたら明らかにC#より無駄なコードが多いから 何でもかんでもこれというわけにはいかないけどね。
74 名前:デフォルトの名無しさん mailto:sage [2009/06/26(金) 15:59:41 ] .NETが凄いんじゃなくて、IronPythonを実装した人が凄いと思う。 あの人、元々は.NETを否定する論文書くために実装してたのにw
75 名前:デフォルトの名無しさん mailto:sage [2009/06/26(金) 16:06:03 ] 論文書いてるうちに、こうやったらできるんじゃね?と思って作ってみたらナイスにうごいちゃったんだっけか。たしかw
76 名前:デフォルトの名無しさん mailto:sage [2009/06/28(日) 18:20:03 ] もうちょっと踏み込んで、Squirrelみたいにスタックレス実装にしたらできることも 色々増えるんだけどねぇ>IronPython まあSquirrelのパフォーマンスを考えると、 その分処理能力が落ちちゃうのかと思わないでもないが。
77 名前:デフォルトの名無しさん mailto:sage [2009/07/01(水) 07:23:03 ] 久しぶりの更新きた Squirrel 2.2.3 stable June 30, 2009 -added sq_getfunctioninfo -added compile time flag SQUSEDOUBLE to use double precision floats -added global slot _floatsize_ int the base lib to recognize single precision and double precision builds -sq_wakeupvm can now resume the vm with an exception -added sqstd_format -generators can now be instantiated by calling sq_call() or closure.call() -fixed a bug in sqstd_printcallstack(thx takayuki_h) -fixed modulo by zero(thx jup) -fixed negative enums and constants -fixed generator crash bug if invoked as tail call (thx Mr.Accident) -fixed some minor bug
78 名前:デフォルトの名無しさん mailto:sage [2009/07/01(水) 10:46:11 ] すごい久々だね 開発続いてるのがありがたい
79 名前:デフォルトの名無しさん mailto:sage [2009/07/01(水) 12:02:12 ] Squirrelの作者さんは答えてくれるときはとても誠実に返答してくれるんだが、 要望出しても無視されてそのまま終わっちゃうことが多いんだよな。(フォーラムにて) 直接メールを出したほうがいいのかなぁ。
80 名前:デフォルトの名無しさん mailto:sage [2009/07/01(水) 13:29:07 ] squirrelってまだ一人で開発してるん?
81 名前:デフォルトの名無しさん mailto:sage [2009/07/01(水) 19:46:32 ] そういえばRMSがC#は危険だと言ったらしいが pythonとsquirrelも2.xの開発がいつまで続くか気になるなあ
82 名前:デフォルトの名無しさん mailto:sage [2009/07/01(水) 22:39:03 ] RMSはGNUにとってC#およびMonoが特許侵害を踏まないかという点で危惧してるだけで、 C#の開発者がいなくなるとかそういう話ではない。
83 名前:デフォルトの名無しさん mailto:sage [2009/07/03(金) 02:58:05 ] >>66 とか>>73 がRhino使ったらどんな反応するのか気になる所だが そもそも組み込みでjsてエディタのマクロ言語とかしか見たことなかった・・・。
84 名前:デフォルトの名無しさん mailto:sage [2009/07/07(火) 21:29:11 ] 質問。今sqratテストしてるのですがバインドする関数が int f(int a, int b=1) {return a+b;} のように引数のデフォルト値持ってた時はどうしてますか。理想を言うなら RootTable(vm).Func<int (*)(int, Optional<int,1>)>(_SC("f"),&f); のような感じに綺麗に書けるといいんだけど自分の実力じゃうまく実装できないw ちなみにフォーラムにある5/31付けのsqratの修正版使ってみたら、 エラーメッセージが_SC()で括ってないのでコンパイルエラーになりました。 うぷ主はJITの人みたいけど、あれは使わないで様子見の方がいいのかな。
85 名前:デフォルトの名無しさん mailto:sage [2009/07/07(火) 22:33:38 ] >>84 いやー、sqratの作者さんはJITの人とは別人ですよ。レスは書きましたがー。 一旦2引数の関数として登録して様子を見る、かな。 Squirrelのデフォルト引数はインタプリタが自前でやってるので バインダ側で自動的に取得って言うのは無理っぽいんじゃないかなぁ。 理屈上はデフォルト引数をテンプレート型の オブジェクトとして渡してあげればいけそうですが。 ともあれC/C++は関数型言語ではないし、あまり突っ込んで実装するほどのことではない気がします。
86 名前:デフォルトの名無しさん mailto:sage [2009/07/08(水) 00:36:42 ] >>85 そうですね。諦めてSquirrel側で関数定義しようかな。 DXライブラリというのを丸ごとバインドしようとしているのですが、ライブラリのAPIの仕様と Squirrel上の関数の定義が一致していないとC++のソースからプログラム持ってくるのが ややこしくなるので、ディフォルト引数定義しないわけにもいかない事情でして。 Squirrel JIT、オリジナル2.1.2の人と改造版2.2.2の人が別なのを忘れておりました。すいません。 ttp://squirrel-lang.org/forums/1/3314/ShowThread.aspx の 05-31-2009, 1:04 PM のZIPです。 最初の"I tried to bind with Sqrat-0.6."(オレはSqrat-0.6で固まろうとした)あたりから不安だったり...
87 名前:デフォルトの名無しさん mailto:sage [2009/07/08(水) 01:26:52 ] >>86 投稿している改変版ではフォーラムのレスであげている不具合は修正されてるよ。 ただ、自分のプロジェクトで正常に動かなかったのは本当。 もーちょっと色々動かしてほしいところだね。
88 名前:デフォルトの名無しさん mailto:sage [2009/07/08(水) 23:11:57 ] 不具合の2個目の方は、文法的におかしな英文で意味不明なんですが このスレを読むと、どうも>>41 の人が言ってる話の関連のようですね。 ありがたく使わせてもらうことにします。レス下さった方ありがとうございました。
89 名前:デフォルトの名無しさん mailto:sage [2009/07/09(木) 00:41:06 ] >>88 >Cannot call method appended at Squirrel script as members of the class > to binded C++ Classes includes meta-methods[_add/_mul/...]. > The hook getter [_get] should return false if the key is unknown. 直訳: 呼び出すことができない、メソッドを、それはSquirrelスクリプトで追加された、 メンバとして、それはクラスの、それはバインドされたC++クラスであり、 メタメソッド『_add/_mul/...』を含む。 hook getterである『_get』はfalseを返すべきである、もしkeyが未知ならば。 意訳: Squirrelスクリプトで(クラスに)追加したメソッドを呼び出すことができない。 これ(クラス)はC++のクラスをバインドしたものでメタメソッド『_add/_mul/...』を含む。 もしもしkeyが未知の場合、hook getterである『_get』はfalseを返すべきである。
90 名前:デフォルトの名無しさん mailto:sage [2009/07/09(木) 00:52:42 ] bindedKansu readedMojisu
91 名前:デフォルトの名無しさん mailto:sage [2009/07/09(木) 01:30:25 ] 直訳: クラスらのメンバーらとしてのSquirrelスクリプトの一点に呼び出しメソッドを メタメソッド[_add/_mull/...]を含むbinded C++クラスへ追加されられない。 もし例のキーが未知ならば例のフックを取得する関数[_get]はfalseを返すべきだ。 methodにtheがない、bindの過去分詞はbound、hookをゲットする、その他もろもろ…
92 名前:デフォルトの名無しさん mailto:sage [2009/07/09(木) 03:08:02 ] もしかして もしかして lua にはインクリメント演算子がないのか..!?
93 名前:デフォルトの名無しさん mailto:sage [2009/07/09(木) 03:19:05 ] >>92 ttp://www.23ch.info/test/read.cgi/tech/1205208141/776-783
94 名前:デフォルトの名無しさん mailto:sage [2009/07/10(金) 00:38:39 ] newEnv = {}; defaultEnv = getfenv(0); for k, v in pairs(_G) do newEnv[k] = v; end setfenv(0, newEnv); hoge = 10; setfenv(0, defaultEnv); print(hoge); 書き換えたグローバル環境(newEnv)にhoge=10を書き込んでるはずなのに Lua5.0/5.1でこれで出力がnilにならないのなんでよ "グローバル環境テーブル"=グローバル変数が属してるテーブルってのが間違い?
95 名前:デフォルトの名無しさん mailto:sage [2009/07/10(金) 14:54:20 ] >>92 シェルスクリプトにもLispにもTclにもRubyにもPythonにも、 インクリメント演算子なんて無いんだよ。
96 名前:デフォルトの名無しさん mailto:sage [2009/07/10(金) 17:25:55 ] Luaの変数をC側から取得する前に、 実際に変数が存在するかの確認ってできませんか?
97 名前:デフォルトの名無しさん mailto:sage [2009/07/10(金) 21:46:15 ] >>94 setfenv(0,env)だと現在のスレッドの環境が変わる。 現在実行中の関数の環境を変えるにはsetfenv(1,env)で。 適当にまとめてみた ・グローバル変数の参照・代入…実行中の関数の環境 ・getfenv(0)/setfenv(0,env)…スレッドの環境 ・getfenv(1)/setfenv(1,env)…実行中の関数の環境 ・関数の中で作られた関数は親の環境を受け継ぐ 例: function f() local g = function() end return g end -- fは実行中のチャンクの環境を受け継ぎ、gはfの環境を受け継ぐ。 ・load*系で作った関数はスレッドの環境を受け継ぐ 例: local t = setmetatable({hoge="t"},{__index=_G}) hoge="main" print(t,hoge) setfenv(0,t) -- スレッドの環境が変更される print(getfenv(1),getfenv(0),hoge) -- 実行中の関数はそのまま loadstring[[ print(getfenv(1),getfenv(0),hoge) ]]()
98 名前:デフォルトの名無しさん mailto:sage [2009/07/11(土) 07:26:02 ] >>97 詳しいサンプルテラthx スレッドの環境が問題なるのはload*系だけなのねorz
99 名前:デフォルトの名無しさん mailto:sage [2009/07/12(日) 13:04:59 ] Lua Performance Tips - Radium Software d.hatena.ne.jp/KZR/20090712/p1 > Lua Programming Gems は, Lua のプログラミングテクニックについてまとめた, > いわゆる「Gems本」だ。公式ページでは第2章 "Lua Performance Tips" を > サンプルとして無料公開しており, PDF 形式でダウンロードして読むことができる。 > この内容がなかなか面白い。 > 最も基本的なポイントであるグローバル変数とローカル変数の違いから, > table における配列とハッシュの扱いについて,文字列の内部的な扱いについて, > 等々, Lua におけるパフォーマンスの要点について触れている。 > (略) 続きはサイトで
100 名前:デフォルトの名無しさん mailto:sage [2009/07/12(日) 22:06:29 ] sqrat0.7
101 名前:デフォルトの名無しさん mailto:sage [2009/07/13(月) 15:25:37 ] >>96 sugarpot.sakura.ne.jp/yuno/html/lua51_manual_ja.html#pdf-_G
102 名前:デフォルトの名無しさん mailto:sage [2009/07/13(月) 23:27:37 ] >>100 うほっ。更新内容見てフイタ。 IronPythonは事実上.NET側のオーバーロードをサポートできてないみたいだな。 明示的に書けば読めないことも無いようだが、 これで実用になるとはとても信じられない。 blogs.msdn.com/haibo_luo/archive/2007/10/11/5413239.aspx
103 名前:デフォルトの名無しさん mailto:sage [2009/07/14(火) 01:06:33 ] >>102 MessageBoxあたりで試せばすぐわかるが普通に呼べんぞ? てゆーかなんでいきなりIronPython?
104 名前:デフォルトの名無しさん mailto:sage [2009/07/14(火) 09:26:14 ] >>95 Lisp には演算子っていう概念がないからちょっと違うけど、inc ならあるよ。 Lua の代入文の = も演算子じゃないんだよな。代入文は式じゃないから。 >>96 Lua は変数の値が nil なら定義されていないっていう意味になるので、 値を取得してみて nil かどうかを調べればいいんじゃないかな。 厳密には、グローバル変数はテーブルのフィールドとして定義されていて、 値が nil ならそのキーは存在しないことと同値なので。
105 名前:デフォルトの名無しさん mailto:sage [2009/07/14(火) 10:16:10 ] >>103 MessageBoxは試してなかったけど、確かにそうだよなぁ。 IronPython呼び出し用に再定義してあげないといけないかも。 オレ、以前はSquirrel党だったんだけど今はIronPython方面に。 組み込みスクリプトとしてはアリだと思うんだけど、どうだろう。
106 名前:デフォルトの名無しさん mailto:sage [2009/07/14(火) 15:38:04 ] Lua > Python: PythonはC関数を登録してスクリプトから呼び出すのが結構めんどくさい。 コルーチンに制限がある。同じ関数内でしか yieldできないし、yield で引数や戻り値の指定ができない。 独自のローダーを使った import 実装がとにかく面倒。 lua なら lua_load に自分定義のロード関数わたすだけでOK Pyhton > Lua: スタックではなく、C上でLua変数はすべて PyObject として表現されるのでCソースの可読性が高い。 関数も整数も全部 PyObject としてC側の変数に保存する事ができる。 環境が充実。 ゲーム用途で組み込んでいる自分としては、コルーチンの使いやすさと、 自作ローダーでのロードが楽(ゲーム用の圧縮ファイルから直接スクリプトを呼び出す必要がある) な点でLua圧勝。 もしツールに組み込むんだったらソースの読みやすさ+ライブラリ充実さで断然 Python Eclipse + PyDevが使いやすいのも勝ち点。
107 名前:デフォルトの名無しさん mailto:sage [2009/07/14(火) 18:43:12 ] わざわざ.NETやMonoに依存したくない
108 名前:デフォルトの名無しさん mailto:sage [2009/07/14(火) 21:40:20 ] >>100 2日で0.71に上がってるからバグでもあったのかと思ったら、 バインドしたC++の関数の引数にSquirrel関数を渡せるようにしてほしいと 要望もらって一日で作ってきてるんですね。 Kanryuさんのパッチも入ったし仕事はやいぞ。
109 名前:デフォルトの名無しさん mailto:sage [2009/07/15(水) 00:50:51 ] AngelScript|Д`)<俺らの話題全然ないな GameMonkey|Д`)<全くだ CRIScript|Д`)<全くだ
110 名前:デフォルトの名無しさん [2009/07/15(水) 01:41:13 ] ttp://www.chaiscript.com/ > ChaiScript | Easy to use scripting for C++
111 名前:デフォルトの名無しさん mailto:sage [2009/07/15(水) 02:24:00 ] チャイってミルクティーやん と思ったらロゴがほんとにミルクティーだw
112 名前:デフォルトの名無しさん mailto:sage [2009/07/15(水) 02:28:39 ] Squirrelってリスやん
113 名前:デフォルトの名無しさん mailto:sage [2009/07/15(水) 06:59:47 ] Luaを組み込んである字幕作成ソフトAegisub ttp://www.aegisub.net/ ttp://g-mark.jpn.org/index.php?Aegisub 字幕スクリプトの整形やエフェクトにLuaを利用してる ライセンスはBSD、ソースは、 ttp://svn.aegisub.net/
114 名前:デフォルトの名無しさん mailto:sage [2009/07/15(水) 19:21:30 ] >>106 Python のyield は引数や戻り値の指定できるよ Stackless Python なら同じ関数でしかyield使えないという制限もなかった気がするけどうろ覚え
115 名前:デフォルトの名無しさん mailto:sage [2009/07/16(木) 10:35:29 ] >>114 レスを見てジェネレータ関係を触ってみたら、 Pythonのバージョンによる挙動の差異が如実に出ててビビッた。 3.0系はprint文が関数化されて書式に互換性が無いとか、 ジェネレータのnext()メソッドが使えなくなってるとか。 IronPythonの現行版はまだ2.5系で、今年中に2.6系互換になる予定なのか。 オレには3.0はまだ新しすぎたようだ!
116 名前:デフォルトの名無しさん mailto:sage [2009/07/16(木) 13:54:53 ] >Python のyield は引数や戻り値の指定できるよ www.python.jp/doc/nightly/ref/yield.html 本当だ、気づかなかった.... orz
117 名前:デフォルトの名無しさん mailto:sage [2009/07/29(水) 10:08:15 ] lua_newthread だとグローバル変数が共有されちゃうけど、 グローバル変数を独立させるようにできないの? コードを共有して変数だけ独立させたいんだけど。 ... って書いてて思ったけど、結局関数もグローバル変数と同じなんだから lua_newstate でいいのか。
118 名前:デフォルトの名無しさん mailto:sage [2009/07/30(木) 02:48:48 ] LUAのコルーチンの中から、C++側で定義された構造体を取得し、 そのメンバの値を変更したいのですが、変更するコードをスクリプトに 記述した場合、そのコルーチンをresumeするLUAの関数をC++から何度か呼ぶと luabind::detail::unrefというところで例外が出てしまいます struct Test { int a; Test(){} }; という構造体があって、luabindで luabind::module(L) [ luabind::class_<Test>("Test") .def(luabind::constructor<>()) .def_readwrite("a", &Test::a) として、コルーチンの中で t=Test() t.a=0 の2行を書くと例外になります この2行をコメントアウトすると、何度呼んでも例外が出ません また、この2行をコルーチンでない普通の関数に記述してC++から呼んでも 例外が出ません なぜコルーチン内から構造体を使用するコードを書くと例外が出るのでしょうか
119 名前:デフォルトの名無しさん mailto:sage [2009/07/30(木) 06:10:29 ] luabind は使ったことがないので想像ですが、 コルーチンから C の関数が呼ばれるときは lua_State(L の値)が違うから、 それが問題になってたりしないかな?
120 名前:デフォルトの名無しさん mailto:sage [2009/07/30(木) 07:27:21 ] >>119 ありがとうございます すみません、質問しておいて何ですが、以下のフォーラムの記事に よるとどうやらluabindにバグがあったみたいで、仰るとおりlua_Stateの 値が関係してるようです(英語がよく分からないので間違っているかもしれません) それでluabind/detail/ref.hppを記事の下にあるものに置き換えたところ、 今のところ例外が出ずに動いています。。 ttp://www.nabble.com/Re:-Garbage-collector-crashes-if-luabind-objects-are-created-in-a-lua-coroutine-td24251470.html
121 名前:デフォルトの名無しさん mailto:sage [2009/07/31(金) 16:36:17 ] lua_resume(ls, ...) で中断しているスクリプトがあるんだけど、 再開するのではなく、リセットして最初から実行しなおしたい場合がある。 このとき、どうすればいい? マニュアルには lua_newthread で作ったスレッドは解放しなくていい、 GCが管理すると書いてあるけど、さすがにいきなり ls = lua_newthread(..); って上書きするんだと、いつまでたっても古い ls の内容が削除されないよね? だってLua側からしてみれば、古い ls はあくまでも中断してるのであって、 いつ再開されるかわからないからGCで回収できないし、 古い ls はもはや不要になったよー ってことをまったく Lua 側に知らせてないし。 かといって、明示的に ls が不要になったことを伝えるために lua_close(ls); ls = lua_newthread(...); lua_resume(ls, ...); とやってみると、lua_newthread で内部エラーが発生する(メモリ違反ぽい) どうすればいいですか?
122 名前:デフォルトの名無しさん mailto:sage [2009/07/31(金) 18:37:55 ] >>121 >いつ再開されるかわからないからGCで回収できない んな事はない。 スレッドでも他のデータでも、参照できなくなったらGCで回収される という事に変わりはない。
123 名前:デフォルトの名無しさん mailto:sage [2009/07/31(金) 18:56:50 ] >>122 でも C のレベルでは、参照されているかどうかってわからないんじゃない? つまり、lua_newthread() した直後は、 Lua のオブジェクトからは参照されていない thread ができるわけですよね。 逆にいうと、lua_newthread() しただけだとどこからも参照されていない事になるから、 lua_setglobal か何かを使って、どこかから参照してあげないといけないとか?
124 名前:デフォルトの名無しさん mailto:sage [2009/07/31(金) 19:50:44 ] どこのlua_newthreadの解説読んでるのか知らんが、 「新しいスレッドを"スタックに積み"……」って書いてないか?
125 名前:デフォルトの名無しさん mailto:sage [2009/07/31(金) 19:59:52 ] www.lua.org/manual/5.1/manual.html#lua_newthread ここみてますけど、でもさすがに、スタックに積んだままじゃほかのことできないでしょ。 元の質問された方がどういう風に使っていたかによるけど。
126 名前:デフォルトの名無しさん mailto:sage [2009/07/31(金) 20:09:46 ] lua_newthreadの直後はC関数のスタックから「参照」されてるし そのあとLuaで参照したいなら戻り値なりグローバル環境なりに押し込めばいいし C側だけで管理したいならレジストリ+luaL_refとか使えばいいだろ 何がしたいんだかわかんねーよ
127 名前:デフォルトの名無しさん mailto:sage [2009/07/31(金) 20:12:10 ] 新しいスレッドを積むのはいいんだけど、 古いスレッドが不要になったということをどうやってLUAに知らせるの? 最初に ls = lua_newthread(...); lua_resume(ls, ...) を実行したとして、ls は中断状態のまま残っていると。 で、中断状態をやめて、最初から実行したいということで、いきなり ls = lua_newthread(...); lua_resume(ls, ...) をもう一度呼び出すと、古い ls が上書きされるけど、古い ls への参照も、 なにもかもまったくいじっておらず、ただ単に新しいスレッドを追加しただけにすぎないわけで。 古い ls の参照カウンタをデクリメントするなり、古い ls への参照を 削除するなりの処理がまったく入っていないと。
128 名前:デフォルトの名無しさん mailto:sage [2009/07/31(金) 20:38:13 ] C++とLuaスクリプトの連携をしたいお年頃なんですが、 toluaとluabindだったらどちらが安定してる感じですか?
129 名前:デフォルトの名無しさん mailto:sage [2009/07/31(金) 21:20:37 ] >>127 だから削除したいならスレッドの参照を潰せばいいだけでしょ? 自分で最後に答え書いてるじゃん! 中断中のコルーチンが参照されなくなった場合に GC 対象になるかどうかは マニュアルにも明言されてない、どっちなの? って質問なら確かにわかりにくいとは思うが。 int main(int argc, char* argv[]) { lua_State* L = lua_open(); luaL_openlibs(L); lua_State* thread = lua_newthread(L); luaL_loadstring(thread, "print('co1'); coroutine.yield(); print('co2');"); lua_resume(thread, 0); //lua_settop(L, 0); lua_gc(L, LUA_GCCOLLECT, 0); lua_resume(thread, 0); lua_close(L); return 0; } lua_newthreadで積んだスレッドを潰す処理であるlua_settopの行のコメントを削除すると 二回目のlua_resumeの時点で落ちるところから「GC対象になる」が正解みたいやね。
130 名前:デフォルトの名無しさん mailto:sage [2009/07/31(金) 21:27:07 ] >>127 は根本的なところを理解してないようだ。スタックにあるんだからpop すればいいんだよ。 まず lua_State *base = lua_newstate(); lua_State *ls = lua_newthread(base); は、 lua_State *base = lua_newstate(); lua_newthread(base); lua_State *ls = lua_tothread(base, -1) と意味的には等価ね。 ここで ls は、あくまでスタック上にあるスレッドの情報を、 直接ポインタとして参照してるだけで、別にリファレンスを持ってるわけではない lua_newthread がこれを返してるのは、単に便利だからにすぎない この状態で、lua_pop(base,1) することで、スタックの末尾にあるもの=さっき作ったスレッドが 破棄されて解放されることになる。これでスレッドが破棄された後に ls にアクセスすると、 実体がなくなってるポインタの参照になるから誤動作を引き起こす 一般的には、スレッドをスタックにつんだままにしとくのはわけわかになるので、 >>126 の言ってる通りに管理することになる
131 名前:デフォルトの名無しさん mailto:sage [2009/07/31(金) 21:52:47 ] >>129 お前も使い方間違ってるよ・・・
132 名前:131 mailto:sage [2009/07/31(金) 21:59:29 ] と思ったけど、俺が間違ってる気がしてきた・・・ メインスレッドのスタックに、新しいスレッドと関数と引数を積んでlua_resumeを呼ぶ と思ったけど、違うのか
133 名前:デフォルトの名無しさん mailto:sage [2009/07/31(金) 22:01:02 ] >>131 え? それだけ言われてもわかんない、どこどこ、教えて!
134 名前:デフォルトの名無しさん mailto:sage [2009/07/31(金) 22:04:32 ] >>132 ってなんじゃいゴルァ!w いやそこは合ってるはずだよ、とゆーかみんなCで組み込むなら標準ライブラリのソース読もうぜ 組み込みの基本からトリッキーなものまで一通りそろってるぜ
135 名前:デフォルトの名無しさん mailto:sage [2009/08/01(土) 20:41:44 ] lbaselib.cのauxresume(L, co, narg)の所を見るとlua_resume(co, narg)となっている。 1番目の引数がLではなくcoだということがマニュアルを読んだだけではわからなかった。
136 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 17:41:02 ] C++でPython組み込んでて 例えば Pythonのソースにスペルミスがあったとして それをC++側で知る方法が全く分からない どなたか分かりませんか
137 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 17:52:13 ] ∩_ 〈〈〈 ヽ 〈⊃ } ∩___∩ | | | ノ ヽ ! ! / ● ● | / | ( _●_) ミ/ Lua!! 彡、 |∪| / / __ ヽノ / (___)
138 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 17:57:43 ] >>136 Pythonスクリプトのコンパイルエラーやら実行時エラーを取得したいっていうこと?
139 名前:デフォルトの名無しさん mailto:sage [2009/08/10(月) 18:02:39 ] >>138 そのとおりです。 PyErr_Print () の出力先を変えればいいのだと思うのですが。。。うまくいきません