1

Ruby用のC++拡張機能を作成していて、Ruby配列オブジェクトからRuby文字列オブジェクトを抽出し、それをC /C++文字列オブジェクトに変換しようとしています。

私はfoo.cppを持っています:

#include <iostream>
#include <ruby.h>

VALUE bar_func(VALUE self, VALUE ary){
    std::string s = StringValuePtr(rb_ary_entry(ary, 0));
    ...
    return 0;
}

extern "C" VALUE rb_cFoo;
VALUE rb_cFoo;
extern "C" void Init_foo(){
    rb_cFoo = rb_define_class("Foo", rb_cObject);
    rb_define_singleton_method(rb_cFoo, "bar", RUBY_METHOD_FUNC(bar_func), 1);
}

およびtest.rb

require "foo"
Foo.bar(["Hello World!"])

コンパイルしようとするfoo.cppと、コンパイラは「単一の用語とオペランドには左側の値が必要です」などのエラーを返します(正確なメッセージではありません。別の自然な言語で表示されるエラーメッセージから変換されます)。それは私の使用法に関するものですStringValuePtr。私は何を間違っているのですか、そしてそれをどのように修正できますか?

4

1 に答える 1

2

まず、代入演算子に適しStringValuePtrたnullで終了するC文字列を返しません。マクロも使用する必要があります。このマクロもパラメーターとして使用します。StringValueCStrVALUE

StringValueCStr次のように定義されます。

#define StringValueCStr(v) rb_string_value_cstr(&(v))

rb_string_value_cstr関数のシグネチャは次のとおりです。

char * rb_string_value_cstr(volatile VALUE *ptr)

マクロ展開後、コードは次のようになります。

std::string s = rb_string_value_cstr(&rb_ary_entry(ary, 0));

あなたのコードは私には間違って見えません。各部分を別々の行に配置して、エラーの原因を絞り込むことができるかどうかを確認してください。

VALUE entry = rb_ary_entry(ary, 0);
char * c_str = StringValueCStr(entry);
std::string str = c_str;
于 2012-04-18T16:00:59.980 に答える