嵌入CRuby脚本引擎的一个历史遗留问题和解决方案
2017 年 2 月 27 日
最近又需要嵌入CRuby,又遇到了这个问题,
主要是当使用net/http等socket相关的库时,会提示找不到read_nonblock方法。
这个问题的解决方案很简单,补充一个定义即可
1 2 3 4 5 | class IO def read_nonblock(size, buf = nil, exception) __read_nonblock(size, buf, exception) end end |
但是使用ruby或者irb时就没有这个问题,为什么呢
(这也不是操作系统相关的问题,虽然我用的是windows)
irb下通过IO.instance_method(:read_nonblock).source_location可以发现这个方法的定义在一个叫”<internal:prelude>”的文件中定义,显然是内部自己的奇怪操作。
这个定义可以通过ruby_init_options函数来初始化,然而。
然而经过搜索发现这个函数一直有人提出,将它导出作为feature,结果从1.9到2.4都没有实行,这个函数直到现在,现成编译的版本从未导出符号。
所以,现在初始化ruby解释器,如果不想从源码修改去掉函数的static存储类关键字这里开始,一个比较合适的写法是:
1 2 3 4 5 6 7 8 9 10 11 12 13 | int argc = 0; char **argv = 0; static char* args[] = {(char *)"ruby", #ifdef WIN32 (char *)"nul" #else (char *)"/dev/null" #endif }; ruby_sysinit(&argc, &argv); ruby_init(); ruby_init_loadpath(); ruby_process_options(2, &args); //假装有个ruby程序执行了一个程序,从而隐含调用prelude定义 |