嵌入式红宝石的奇怪行为

时间:2012-09-03 12:51:57

标签: ruby embedded-ruby

我们正在观察嵌入式ruby应用程序上的一个奇怪行为。我们已经将代码简化为极少,并且能够重新生成该问题。以下是详细信息。

1。红宝石代码

#!/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”文件时,我们收到以下错误

主要的未定义方法`loopFunc':对象
NoMethodError

然而,当我们要求在rb文件的顶部一切正常。

我们的第一个猜测是rb_eval_string()在模块AA中执行。所以loopFunc在模块AA中定义而不是全局。因此报告了NoMethodError。当我们在cpp文件中调用AA :: BC.new()。loopFunc()时,该方法被成功调用;这证实了我们的猜测。

这是从嵌入式ruby角度来看的预期行为,因为如果我们需要一个rb文件(而不是.so)与传递给rb_eval_string的代码相同,我们就不会收到任何错误。

1 个答案:

答案 0 :(得分:1)

rb_eval_string()确实定义了调用它的模块中的方法。我们可以使用rb_require / rb_load来获得正确的行为。