嵌入ruby的奇怪行为
我们在嵌入式ruby应用程序上观察到一个奇怪的行为。我们已经将代码精简到最低限度,并能够重新生成问题。详情如下 1。ruby代码嵌入ruby的奇怪行为,ruby,embedded-ruby,Ruby,Embedded Ruby,我们在嵌入式ruby应用程序上观察到一个奇怪的行为。我们已经将代码精简到最低限度,并能够重新生成问题。详情如下 1。ruby代码 #!/usr/bin/env ruby #require "MyLibrary.so" *// Works fine* module AA class BC def initialize end def loadFunction require "MyLibrary.so" *//Gives error* end
#!/usr/bin/env ruby
#require "MyLibrary.so" *// Works fine*
module AA
class BC
def initialize
end
def loadFunction
require "MyLibrary.so" *//Gives error*
end
end
end
#Invoke the method
AA::BC.new().loadFunction
2。MyLibrary.so的源代码
#include "ruby.h"
const char loop[] =
"def loopFunc\n"
"puts \"HERE\"\n"
"end\n"
"begin\n"
"loopFunc()\n"
"rescue StandardError\n"
"puts $!\n"
"puts $!.class\n"
"end\n";
void initialize()
{
ruby_init();
ruby_init_loadpath();
rb_eval_string(loop);
}
extern "C" void Init_MyLibrary()
{
initialize();
}
当我们在rb文件的loadFunction中需要“MyLibrary.so”文件时,我们得到以下错误
未定义main:Object的方法'loopFunc'命名错误 然而,当我们需要在rb文件的顶部时,一切都很好 我们的第一个猜测是rb_eval_string()在模块AA内执行。因此,loopFunc是在模块AA中定义的,而不是全局的。因此,正在报告NoMethodError。当我们在cpp文件中调用AA::BC.new().loopFunc()时,该方法被成功调用;这证实了我们的猜测
从嵌入式ruby的角度来看,这是否是预期的行为,因为如果我们需要一个rb文件(而不是.so),该文件的代码与传递给rb_eval_string的代码相同,那么我们不会得到任何错误。rb_eval_string()确实定义了调用它的模块中的方法。我们可以使用rb_require/rb_load来获得正确的行为。这是一个如何提出清晰的SO问题的示例。