我将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)
。这是通过添加额外的行rb_eval_string("require 'enc/trans/transdb'");
来解决的,但是,我不希望逐个复制由ruby的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(Apparently this has been the case for some time on Windows)。这很麻烦,因为我希望我的应用程序只需双击可执行文件就可以运行,而不需要用户提供指示“bootstrap”脚本位置的命令行参数。
那么,在这种情况下我是否可以使用方便的API或一些咒语来初始化ruby而不需要命令行参数?
请注意,如果可能的话,我希望避免将我的应用程序打包为ruby扩展。
答案 0 :(得分: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文件中的符号,我能够在encdb.so中找到Init_encdb
,并在trans /中找到Init_transdb
transdb.so。所以,我需要这些libs和我的bootstrap脚本,如下所示:
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库。虽然我不能确定我不会遇到更多像这样的问题(我还没有尝试要求一个真正的宝石......)这是一个我更熟悉的解决方案。如果我可以通过一个简单的需求来解决任何即将出现的问题,而不是四处寻找像rb_enc_find_index("encdb");
这样的模糊命令来填充我的初始化代码,那么这似乎是合理的。
我仍然对任何更简单的替代方案感兴趣,并且会暂时接受这个作为答案 - 至少一段时间 - 直到我收到一些确认我正确认识到这一点。