4

組み込みの 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" ファイルを必要とすると、次のエラーが発生します。


main:Object NoMethodErrorの未定義メソッド「loopFunc」

ただし、rb ファイルの先頭で必要な場合は、すべて正常に動作します。

私たちの最初の推測は、rb_eval_string() がモジュール AA 内で実行されるというものでした。そのため、loopFunc はグローバルではなく、モジュール AA 内で定義されています。したがって、NoMethodError が報告されています。cpp ファイル内で AA::BC.new().loopFunc() を呼び出すと、メソッドが正常に呼び出されます。これは私たちの推測を確認しました。

rb_eval_string に渡されたものと同じコードで (.so ではなく) rb ファイルが必要な場合、エラーは発生しないため、これは組み込み Ruby の観点から予想される動作ですか。

4

1 に答える 1

1

rb_eval_string() は、呼び出されたモジュール内のメソッドを定義します。rb_require/rb_load を使用して正しい動作を得ることができます。

于 2012-09-04T13:35:43.287 に答える