[英]RubyInline include another generated file to call a function from that file
我有兩個針對Ruby的C擴展(用於Rails應用程序)。 我使用config.after_initialize
在application.rb
初始化它們。
這是第一堂課:
class Object
require 'inline'
inline do |builder|
builder.c <<-EOC
static VALUE
rb_obj_is_number(){
// code to return Qtrue or Qfalse
}
EOC
end
alias is_number rb_obj_is_number
end
這是第二個(需要從上面使用rb_obj_is_number()
):
class Array
require 'inline'
inline do |builder|
builder.c <<-EOC
static VALUE
rb_ary_some_fun(){
double result = 0;
long i, len = RARRAY_LEN(self);
VALUE *c_arr = RARRAY_PTR(self);
for(i=0; i<len; i++) {
if ( TYPE(rb_obj_is_number(c_arr[i])) == T_TRUE ) {
result += NUM2DBL(c_arr[i]);
}
}
return rb_float_new(result);
}
EOC
end
alias some_fun rb_ary_some_fun
end
嘗試從一個文件調用另一個文件的函數時,出現以下錯誤:
dyld: lazy symbol binding failed: Symbol not found: _rb_obj_is_number
我猜這是因為我沒有在第二個文件中包含第一個生成的文件。 我該怎么做才能使rb_obj_is_number
被編譯器識別?
您的函數在單獨的編譯單元中被聲明為static
,因此rb_ary_some_fun
當然看不到rb_obj_is_number
。 馬上想到兩個選擇:
一種選擇是將rb_obj_is_number
的C實現rb_obj_is_number
一個字符串,兩個builder.c
調用均可訪問。 這將為您提供函數的兩個副本,但:
static
因此不會出現名稱空間問題。 您將擁有以下內容:
# In some library file...
module CUtil
IS_NUMBER = %q{
static VALUE rb_obj_is_number(void) { /*...*/ }
}
end
# When monkey patching Object...
class Object
require 'inline'
inline do |builder|
builder.c CUtil::IS_NUMBER
end
alias is_number rb_obj_is_number
end
# When monkey patching Array...
class Array
require 'inline'
inline do |builder|
builder.c <<-EOC
#{CUtil::IS_NUMBER}
static VALUE rb_ary_some_fun(void) { /*...*/ }
EOC
end
alias some_fun rb_ary_some_fun
end
那是一大堆糾結,所以我不建議這樣做。 不過,在某些情況下,這種方法很有意義。
正確的方法是從C is_number
作為Ruby方法進行調用。將is_number
作為一種方法進行調用可使其被覆蓋,猴子補丁等,就像其他任何方法一樣。 您將使用rb_funcall
這樣的東西:
/* There's no need to call this over and over again inside a loop. */
ID is_number = rb_intern("is_number");
/* ... */
if(rb_funcall(c_arr[i], is_number, 0) == Qtrue) {
result += NUM2DBL(c_arr[i]);
}
另外,我建議您使用正確的函數簽名(即rb_obj_is_number(void)
),以確保編譯器不會以K&R模式結尾。 您還應該調整編譯器的警告標志,以使它大聲抱怨這種事情。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.