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問題的範例。 –