1

Ruby バージョン 2.1.2 を wxWidgets アプリケーションに埋め込み、Windows でコンパイルおよびターゲット設定しています。msvcrt-ruby210.dll へのリンクと呼び出し

ruby_sysinit(&argc, &argv);
RUBY_INIT_STACK;
ruby_init();
ruby_init_loadpath();

基本的な VM と組み込みクラスを実行するには、これで十分です。ただし、アプリケーションから FileUtils や Resolv などの機能を使用するつもりなので、標準ライブラリもアプリケーションにパッケージ化しています。require一部のライブラリは問題なく使用できrequire 'resolv'ますが、エラー報告が表示されるとunitialized constant Encoding::UTF_16LE. ruby.c でいくつかのグーグルと掘り下げた後、次の初期化コードでこれを修正できることがわかりました...

ruby_sysinit(&argc, &argv);
RUBY_INIT_STACK;
ruby_init();
ruby_init_loadpath();
rb_enc_find_index("encdb");

これにより、以前のエラーはクリアされますが、code converter not found (UTF-8 to UTF-16LE). これは追加の行を追加することで修正されますが、Rubyの関数rb_eval_string("require 'enc/trans/transdb'");によって実行される初期化コードを少しずつ複製するのは私の好みではないのでruby_options、Ruby自身の関数のように直接使用しようとしましたmain...

int my_argc = 2;
char* arg1 = "myapp.exe";
char* arg2 = "scripts/bootstrap.rb";
char** my_argv = new char*[2]{arg1, arg2};

ruby_sysinit(&my_argc, &my_argv);
RUBY_INIT_STACK;
ruby_init();
ruby_run_node(ruby_options(my_argc, my_argv));

ただし、これは、アプリケーションを で実行した場合にのみ有効ですmyapp.exe scripts/bootstrap.rb。ruby は私のパラメーターを無視してruby_options、システムが提供する argc と argv の値を使用しているようです (明らかに、これは Windows でしばらくの間当てはまりました)。実行可能ファイルをダブルクリックするだけでアプリケーションを実行し、ユーザーが「ブートストラップ」スクリプトの場所を示すコマンドライン引数を指定する必要がないようにしたいので、これは面倒です。

この場合、コマンドラインパラメータを必要とせずにルビーを初期化するために使用できる便利なAPIまたは呪文はありますか?

可能であれば、アプリケーションを ruby​​ 拡張機能としてパッケージ化する必要は避けたいと考えています。

4

1 に答える 1

0

私は pepper_main.c でこのコードに気づき、これが私が望んでいたことを行っているのではないかと疑っていました。

static VALUE
init_libraries_internal(VALUE unused)
{
  extern void Init_enc();
  extern void Init_ext();

  init_loadpath();
  Init_enc();
  Init_ext();
  return Qnil;
}

私が理解できる限りInit_ext()、Ruby DLL を使用しているので必要ありません。また、拡張機能を静的にコンパイルしていません。ということで、そのまま使ってみInit_encました。このシンボルは msvcrt-ruby210.dll には存在しますが、インポート ライブラリ (msvcrt-ruby210.dll.a) には存在しないため、アプリケーションにリンクできませんでした。lib\ruby\2.1.0\i386-mingw32\enc ディレクトリにある .so ファイルのシンボルを検索するInit_encdbと、encdb.so とInit_transdbtrans/transdb.so で見つけることができました。したがって、以下に示すように、これらのライブラリとブートストラップ スクリプトが必要です。

ruby_sysinit(&argc, &argv);
RUBY_INIT_STACK;
ruby_init();
ruby_init_loadpath();
rb_require("enc/encdb");
rb_require("enc/trans/transdb");
rb_require("./scripts/bootstrap");

これにより、FileUtils および Resolv ライブラリをエラーなしで使用できます。このような問題がこれ以上発生しないとは確信できませんが (実際の gem を要求することはまだ試していません...)、これは私がより快適に使用できるソリューションです。rb_enc_find_index("encdb");初期化コードに散りばめたようなあいまいなコマンドを探し回るのではなく、単純なrequireで今後の問題を解決できる場合、それは合理的だと思われます.

私はまだより単純な代替案に興味があり、これを答えとして受け入れることを保留します-少なくともしばらくの間-私がこれを正しく行っているという確認を受け取るまで.

于 2014-08-22T16:17:43.007 に答える