【问题标题】:Strange behavior with embedded ruby嵌入红宝石的奇怪行为
【发布时间】:2012-09-03 12:51:56
【问题描述】:

我们在嵌入式 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" 文件时,我们会收到以下错误

ma​​in:Object 的未定义方法 `loopFunc'
NoMethodError

但是,当我们在 rb 文件顶部需要时,一切正常。

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

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

【问题讨论】:

  • 这是如何提出明确的 SO 问题的示例。

标签: ruby embedded-ruby


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-29
    • 1970-01-01
    • 2012-03-02
    • 1970-01-01
    • 2012-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多