Project

General

Profile

Actions

Feature #22102

open

C API to obtain a C string from a Ruby String

Feature #22102: C API to obtain a C string from a Ruby String

Added by rhenium (Kazuki Yamaguchi) 4 days ago. Updated 4 days ago.

Status:
Open
Assignee:
-
Target version:
-
[ruby-core:125684]

Description

Extracted from https://bugs.ruby-lang.org/issues/19315#note-35

It would be nice to have a utility function whose sole purpose is to obtain a C string (NUL-terminated and containing no NUL bytes) from a Ruby String. I suggest adding something like the following to the public C API:

/**
 * Returns a pointer to the string contents as a C string. This checks that the
 * string does not contain embedded NUL bytes and that it is properly
 * NUL-terminated.
 *
 * @param[in]  str             String in question.
 * @exception  rb_eArgError    String contents include a NUL byte in the middle.
 * @return     Pointer to its contents.
 * @pre        `str` must be an instance of ::RString.
 */
const char *rb_str_cstr(VALUE str);

While extensions can currently use StringValueCStr(val), there are cases where it's inconvenient.

  • The argument val needs to be addressable and modifiable, even if a type conversion is not needed.

    const char *ptr = StringValueCStr(rb_ary_entry(ary, 0)); // Won't compile
    
  • Repeating StringValue*() calls on the same object to perform different checks is awkward.

    // Let's say, `val_a` and `val_b` are passed as an input, and the types are unknown
    StringValueCStr(val_a); // The result is unusable because the next line can invalidate it
    const char *b = StringValueCStr(val_b); // `val_b.to_str` can mutate `val_a`
    const char *a = StringValueCStr(val_a); // So you have to check `val_a` again
    

Updated by nobu (Nobuyoshi Nakada) 4 days ago Actions #1 [ruby-core:125693]

Expose rb_str_to_cstr?

Updated by rhenium (Kazuki Yamaguchi) 4 days ago Actions #2 [ruby-core:125696]

As @kou (Kouhei Sutou) pointed out in https://bugs.ruby-lang.org/issues/19315#note-36, rb_str_to_cstr() in string.c returns NULL if the string is found to contain NUL bytes in the middle.

IMO an exception more often is desirable for typical use cases in extensions, so my suggestion is to raise ArgumentError, similar to how StringValueCStr() currently behaves.

I don't have a strong opinion on whether the public API should have "to_" in the name or not, but I have a mild preference for a shorter name.

Actions

Also available in: PDF Atom