From: Caleb Clausen Date: 2010-05-06T11:45:10+09:00 Subject: Re: How can I call String#replace (rb_str_replace()) in C API? On 5/5/10, James Masters wrote: >> > How can I do this with the Ruby C API? I looked at rb_str_replace in >> > string.c; however, that is not a public function in the C API. After >> >> Are you using ruby 1.8 or 1.9? 1.9 makes rb_str_replace non-static and >> declares it in intern.h. I don't see it in 1.8's intern.h, so its very > > Unfortunately I am using Ruby 1.8. > >> > I'm really just looking for a way to take a Ruby string VALUE and >> > replace the contents of that object with a C string in the most >> > efficient method possible. Can someone help me in doing this or at >> > least point me in the right direction? >> >> One other option is to fiddle directly with the fields of struct >> RString, but I don't recommend that unless you're really dedicated. > > I am thinking about doing this but it would be a pain and probably > dangerous as you have mentioned. I can probably put something > together with good performance by tweaking the pointer location and > string length but I'll need to get more familiar with the Ruby code > before I attempt something like this. One good thing is that I am > creating the Ruby string to be used as the replacement myself in the C+ > + code on my own so I shouldn't need to do type checking. If anyone > has any pointers on where to find some of the underlying Ruby C data > structures (e.g. ELTS_SHARED and STR_ASSOC flags) then I could use it. BEWARE: if you go this route, you MUST interface correctly with ruby's garbage collector, or else your program will crash mysteriously in unlikely places. Ruby likes to control not only where struct RString is allocated, but also the string buffer it points to. The apis for using those internal memory management facilities are definitely not public, so this gets icky real fast. I've never tried to do this and can't offer any advise about how to fool the garbage collector into thinking that a string buffer you allocated is actually kosher. You're better off trying to call rb_str_replace even tho it is static. Or maybe porting your app to 1.9. (Which is a nontrivial effort.) I can't offer any help with those flags either, other than "Use the source, Luke.". The GC issues are likely to be the biggest challenge. Good luck!