如何使用RubyInline将字符串加载到C方法中

时间:2014-04-11 18:41:02

标签: c ruby inline

我想在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。

干杯,

3 个答案:

答案 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);
}