【问题标题】:How to convert a string taken out from a Ruby array into a C/C++ String如何将从 Ruby 数组中取出的字符串转换为 C/C++ 字符串
【发布时间】:2012-04-18 13:39:37
【问题描述】:

我正在为 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 的使用。我做错了什么,如何解决?

【问题讨论】:

  • 引用运算符&amp; 应该使用左值,即不能应用于常量。
  • @kirilloid 有没有办法修复代码?

标签: c++ ruby ruby-c-extension


【解决方案1】:

首先StringValuePtr does not return a null-terminated C string适合assignment operator。您应该使用StringValueCStr 宏,它也将VALUE 作为参数。

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;

【讨论】:

  • 感谢您的帮助和详细解释。
猜你喜欢
  • 2017-05-20
  • 1970-01-01
  • 2021-05-09
  • 2015-02-11
  • 1970-01-01
  • 2016-11-20
相关资源
最近更新 更多