Using ruby.h to generate C++ vectors and maps

E

Edward Liu

I am trying to use ruby.h to extend Ruby with C/C++. I understand how
to deal with numbers and strings, but I am having trouble finding
documentation about vectors and maps. Let's say I have this function
for example:

VALUE read_values(VALUE self, VALUE object);

The 'object' variable can represent either a Ruby array or a Ruby hash.
If it is a Ruby array, I want to translate it to a vector. If it is a
Ruby hash, I want to translate it to a map. I know for integers, there
is a macro called NUM2INT that converts a Ruby number into a C/C++
integer. For strings, I know that the function StringValueCStr does
what I want. I couldn't find it in the ruby.h documentation, but is
there any similar functionality in ruby.h for translating to vectors and
maps? If so, what is the functionality? If there is not a direct
translation, what would be the best approach to do my task? I'd like to
avoid using another protocol, like SWIG, for this task, if possible.

Thanks,
Edward
 
J

Jason Roelofs

[Note: parts of this message were removed to make it a legal post.]

I am trying to use ruby.h to extend Ruby with C/C++. I understand how
to deal with numbers and strings, but I am having trouble finding
documentation about vectors and maps. Let's say I have this function
for example:

VALUE read_values(VALUE self, VALUE object);

The 'object' variable can represent either a Ruby array or a Ruby hash.
If it is a Ruby array, I want to translate it to a vector. If it is a
Ruby hash, I want to translate it to a map. I know for integers, there
is a macro called NUM2INT that converts a Ruby number into a C/C++
integer. For strings, I know that the function StringValueCStr does
what I want. I couldn't find it in the ruby.h documentation, but is
there any similar functionality in ruby.h for translating to vectors and
maps? If so, what is the functionality? If there is not a direct
translation, what would be the best approach to do my task? I'd like to
avoid using another protocol, like SWIG, for this task, if possible.

Thanks,
Edward
You'll want something like:

VALUE read_values(VALUE self, VALUE object) {
if(rb_obj_is_instance_of(object, "Hash") {

} else if (rb_obj_is_instance_of(object, "Array") {

}
}

API is best found here: http://www.rubycentral.com/pickaxe/ext_ruby.html

Jason
 
E

Edward Liu

I already know how to check if 'object' is an array or a hash. I am
looking for how to translate 'object' from a Ruby array to a C/C++
vector or from a Ruby hash to a C/C++ map.
 
E

Edward Liu

Also, when I do the translation, I don't want to use functions like
rb_ary_new2 or rb_hash_new, since these two functions both return VALUE
objects, not std::vector or std::map objects. I know there is no direct
function in ruby.h to do the translation. I'm wondering if this is a
certain process of function calls in ruby.h to do this. Thanks!
 
J

Jason Roelofs

[Note: parts of this message were removed to make it a legal post.]

Also, when I do the translation, I don't want to use functions like
rb_ary_new2 or rb_hash_new, since these two functions both return VALUE
objects, not std::vector or std::map objects. I know there is no direct
function in ruby.h to do the translation. I'm wondering if this is a
certain process of function calls in ruby.h to do this. Thanks!
Then no, there isn't. If you know that your array / hash is full of a single
type, then the following will work fine:

std::vector<your_type> vec;

for(int i = 0; i < RARRAY(object)->len; i++) {
vec << NUM2INT(rb_array_get(i)); // or STR2CSTR, whatever conversion is
needed
}

But if it's a generic array and you can't guarentee types, you'll have to
make some concessions (like turning the values into strings).

Look through the API, there are methods and macros that will help you.

Jason
 
E

Edward Liu

I'm looking through the documentation for ruby.h and intern.h, and I am
having a problem with trying to be able to access a Ruby hash inside a
C/C++ program. I see that using ruby.h, I have access to rb_hash_new
and a couple other hash functions. However, it doesn't seem that I can
use a function that will return me an array of keys to access the hash.
For example, hash.c in Ruby has a rb_hash_keys functions. However, it
is not accessible through either ruby.h or intern.h. Does anyone know
of any way I can full access to the Ruby hash and array functions for
C/C++?

Thanks!
Edward
 
A

Andre Nathan

Does anyone know of any way I can full access to the Ruby
hash and array functions for C/C++?

You can use rb_funcall():

VALUE hash = ...;
VALUE keys = rb_funcall(hash, rb_intern("keys"), 0);

HTH,
Andre
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,997
Messages
2,570,239
Members
46,827
Latest member
DMUK_Beginner

Latest Threads

Top