我想在Ruby中使用C方法来处理字符串。我在这里找到了一个问题,部分回答了这个问题。 我用这个要点开始尝试:https://gist.github.com/dimus/147023。 它首先尝试将ruby字符串强制为一个C数组。
这是我到目前为止所做的:
#!/usr/bin/env ruby
require 'inline'
class TestC
inline do |builder|
builder.c "
static
void
load_string(VALUE _s) {
VALUE *sv = RARRAY_PTR(_s);
int sl = RARRAY_LEN(_s);
int s[sl];
int i;
for (i=0; i < sl; i++) {
s[i] = NUM2INT(sv[i]);
}
}
"
end
def run_inline
load_string("string")
end
end
test = TestC.new
test.run_inline
不幸的是,for循环中的行使代码段出错。
最近有没有人使用过RubyInline?我使用的是Ruby 2.0.0p451。
干杯,
答案 0 :(得分:2)
你需要有strlen +1大缓冲区才能存储。 +1代表null。
尝试int s[sl+1];
答案 1 :(得分:2)
在您的C代码中,您调用VALUE *sv = RARRAY_PTR(_s);
,因此您将该参数视为Ruby数组,但您使用load_string("string")
调用它 - 即您传递一个字符串。因此,您获得的指针无效,当您尝试使用它时,您将获得段错误。
如果您传入数组(例如load_string(["string"])
,则会修复段错误,但当您尝试在字符串上使用no implicit conversion of String into Integer (TypeError)
时,这将生成NUM2INT
。
您需要确保检查方法的参数类型,并在类型不符合预期时处理案例。
答案 2 :(得分:0)
这是我最后使用的:
static
void
string_parse(VALUE _s) {
int i,sl,longest=0;
char * c_str;
sl = RSTRING_LEN(_s);
c_str = StringValueCStr(_s);
for (i=0;i<sl;i++) {
// do stuff here
}
return INT2NUM(longest);
}