Converting strings in c extension

While trying to bind some old C code to ruby I ran into trouble
converting strings. The function in question requires two string
arguments (const char*). This is the relevant part of my binding:


static VALUE rb_ldist(VALUE s, VALUE t)
{
return INT2FIX(ldist(StringValuePtr(s),StringValuePtr(t)));
}

Compilation works without warnings, but when I try to use the function
in ruby with

ldist ‘foo’,‘bar’

it gives me

can’t convert Object into String (TypeError)

Why is it an Object and not a String?

I also tried to use RSTRING(s)->ptr insead of StringValuePtr, but that
gave me an invalid pointer.

Any suggestions on what to do here?

thanks in advance for any help.

Niklas C. wrote:

While trying to bind some old C code to ruby I ran into trouble
converting strings. The function in question requires two string
arguments (const char*). This is the relevant part of my binding:

Try adding the following lines to see what the objects really are:


static VALUE rb_ldist(VALUE s, VALUE t)
{
rb_p(s);
rb_p(t);
return INT2FIX(ldist(StringValuePtr(s),StringValuePtr(t)));
}

(Btw, README.EXT should mention this function. It’s very useful.)

On Tue, 2008-04-29 at 11:30 +0900, Joel VanderWerf wrote:

(Btw, README.EXT should mention this function. It’s very useful.)

Argh. I’ve been doing

rb_funcall(rb_mKernel, rb_intern(“p”), 1, obj);

all this time…

Thanks for mentioning this :slight_smile:

Andre

Whow, that really gave me a hint!
Doing
ldist ‘foo’,‘bar’
now prints:

main
‘foo’

So for some reason main is given as the first argument. Does ruby always
do that? doesn’t make much sense to me…

Anyway, I solved the problem by adding another (first) parameter to
rb_ldist, but still specifying 2 parameters down in the rb_define_method
call. Seems like a dirty hack but it’s working, thank’s a lot :wink:

Joel VanderWerf wrote:

Niklas C. wrote:

While trying to bind some old C code to ruby I ran into trouble
converting strings. The function in question requires two string
arguments (const char*). This is the relevant part of my binding:

Try adding the following lines to see what the objects really are:


static VALUE rb_ldist(VALUE s, VALUE t)
{
rb_p(s);
rb_p(t);
return INT2FIX(ldist(StringValuePtr(s),StringValuePtr(t)));
}

(Btw, README.EXT should mention this function. It’s very useful.)

On Mon, Apr 28, 2008 at 10:15 PM, Niklas C. [email protected]
wrote:

Whow, that really gave me a hint!
Doing
ldist ‘foo’,‘bar’
now prints:

main
‘foo’

So for some reason main is given as the first argument. Does ruby always
do that? doesn’t make much sense to me…

The first argument is always ‘self’ - the object that the method is
being called on. Your function definition should always have 1 more
parameter than rb_define_method specifies.

Anyway, I solved the problem by adding another (first) parameter to
rb_ldist, but still specifying 2 parameters down in the rb_define_method
call. Seems like a dirty hack but it’s working, thank’s a lot :wink:

So it’s not really a dirty hack - just rename your dummy to ‘self’ and
you are doing the right thing.

-Adam