From: KIMURA Koichi Date: 2007-10-18T18:24:54+09:00 Subject: [ruby-list:44124] Re: Windowsアプリにrubyを組み込んだときのエラーメッセージ 木村です。 とりあえず書ける こと/もの を書いておこうと思い、最低限のことをまと めたつもりです。前回は REDME.EXT と提案しましたが、 READMEの方が 良いかもしれないと考え直して作業したので、README.ja に対する 差分になっています。 On Mon, 15 Oct 2007 02:24:12 +0900 "U.Nakamura" wrote: > 以下、雑多な参考情報(釈迦に説法): > * ruby組み込みアプリケーションの例としてmain.cとwin32/winmain.c > が標準で添付されている :) > * erubyとmodrubyは好例と思う。configure.rbもあるし(自前で各 > プラットフォームに対応したMakefileを用意するのは大変) > * 組み込みと言っても、rubyインタプリタをラップする形のもの > と、単にスクリプトを一発叩きたいだけのもの、rubyオブジェ > クトを自前で操作しまくるもの、とは扱い方がいろいろ違うか > もしれない > * マルチスレッド(rubyの、でなく)なアプリケーションではさら > に特別な注意が必要 > * 1.9では初期化のおまじないが変更されている ・マルチスレッドの扱いが面倒だというのはわかりますが、具体的に 「こういう目にあった」といった例はありますか? ・erubyとmod_rubyはこれから見ます。 ・組み込み方云々は Pythonのドキュメントの書き方を参考にこれから 練りたいと思います。が、そうすると独立したドキュメントした方が よいかも… #うへえ それと一つ質問なんですが、 + RUBY_INIT_STACK これがないとまずいだろうとは思いますが、抜けた場合に インタプリタがクラッシュしたりしますでしょうか? --- README.ja.1~ 2007-02-20 16:37:34.000000000 +0900 +++ README.ja 2007-10-16 14:24:02.883750000 +0900 @@ -144,6 +144,78 @@ クにフラッシュするアセンブラコードを追加する必要があるかも知 れません. +* Rubyインタプリタを組み込んだアプリケーションを作成するとき +の注意事項 + +・ruby.h を忘れずに include すること! + +特にWindows用に作成する場合、Windows固有の事情によってインタ +プリタ外部からアクセスする変数や関数は特別な宣言をしておかな +けれなりません。もしそのような宣言に不備があった場合、リンク +に失敗したりリンクには成功して実行ファイルが作れたとしてもい +ざ実行してみると正しくアクセスできないということになります。 + +このようなことを防ぐために、あなたの作っているソースコードで +他のヘッダファイルよりも先に + +#include "ruby.h" + +を行ってください。 + +rubyインタプリタを組み込んだアプリケーションの参考になるもの +としてrubyインタプリタそのものがあります。つまり、Rubyインタ +プリタの本体はDLL(Windows以外のプラットフォームなら共有オブ +ジェクト)にあってruby インタプリタの実行ファイルは、必要な設 +定をしてインタプリタを呼び出すだけのものになっているのです。 + +実際に main 関数をみてみると以下のようになっています: + + +#include "ruby.h" + +#ifdef __human68k__ +int _stacksize = 262144; +#endif + +#if defined __MINGW32__ +int _CRT_glob = 0; +#endif + +#if defined(__MACOS__) && defined(__MWERKS__) +#include +#endif + +/* to link startup code with ObjC support */ +#if (defined(__APPLE__) || defined(__NeXT__)) && defined(__MACH__) +static void objcdummyfunction( void ) { objc_msgSend(); } +#endif + +int +main(argc, argv, envp) + int argc; + char **argv, **envp; +{ +#ifdef _WIN32 + NtInitialize(&argc, &argv); +#endif +#if defined(__MACOS__) && defined(__MWERKS__) + argc = ccommand(&argv); +#endif + + { + RUBY_INIT_STACK + ruby_init(); + ruby_options(argc, argv); + ruby_run(); + } + return 0; +} + +Windows用の場合、プログラムの引数で与えられたワイルドカードの展開を +行うために NtIninialize という関数を呼び出してその処理をしています。 +1.9ではこの関数を初めとして幾つかの名前が変わっていますので注意 +してください。 + * 配布条件 -- 木村浩一