Search code examples
rubycextension

Updating C extension for Ruby 1.9


I'm updating a fairly old C extension bound to a ruby gem that I didn't write. Currently, when I execute the script that will use the C extension, I get this error:

symbol lookup error: /path/to/lib.so: undefined symbol: rb_str2cstr

There was also problems with STR2CSTR in the same library, which was fixed by replacing it with StringValuePtr. My initial thought was to replace rb_str2cstr with rb_string_value_ptr, but when I try that, the C extension will not build. I'm by no means a C programmer, and am not sure where to go with this. I know I have to replace rb_str2cstr with its replacement, but I can't seem to figure out what that is.


Solution

  • In the source of ruby.h for Ruby 1.8.7-p357 it has:

    /* obsolete API - use StringValue() */
    char *rb_str2cstr _((VALUE,long*));
    

    StringValue returns a VALUE that you can use RSTRING on to get the length and char * pointer:

    RSTRING(s)->len /* length */
    RSTRING(s)->ptr  /* char pointer */
    

    So if the existing code looked something like this:

    VALUE str = ...; /* The ruby String */
    
    long  len;
    char* words;
    words = rb_str2cstr(str, &len);
    

    Then change it to:

    VALUE str = ...;
    str = StringValue(str);
    
    char* words = RSTRING(str)->ptr;
    long  len   = RSTRING(str)->len;
    

    If you're sure that str is already a Ruby String then you could omit the StringValue call, but it'd be safer to keep it.