4
我们在嵌入式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
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” 文件的源代码,我们得到以下错误
未定义的方法`loopF unc'为主体:对象
NoMethodError
但是,当我们需要在rb文件的顶部一切工作正常。
我们的第一个猜测是,rb_eval_string()获取模块AA内执行。所以loopFunc在模块AA内部被定义,而不是全局的。因此,正在报告NoMethodError。当我们在cpp文件中调用AA :: BC.new()。loopFunc()时,该方法被调用成功;这证实了我们的猜测。
这是从嵌入式ruby的角度来看的预期行为,因为如果我们需要使用与传递给rb_eval_string相同的代码的rb文件(而不是.so),我们不会收到任何错误。
这是一个如何提出明确SO问题的范例。 –