From: Charles Mills Date: 2005-04-05T04:19:43+09:00 Subject: Re: Extension question Joe Van Dyk wrote: > On Apr 4, 2005 10:35 AM, Joe Van Dyk wrote: > > On Apr 4, 2005 8:34 AM, Charles Mills wrote: > > > > > > > Are there any general rules of thumb that you use when writing > > > extensions? > > > > > > http://www.ruby-talk.org/cgi-bin/scat.rb/ruby/ruby-talk/47700 > > > > > > You shouldn't be able to cause your extension to seg fault from Ruby. > > > That may sound like a joke, but I just mean using StringValue, > > > NUM2LONG, etc before you starting using Ruby objects in C. > > > > > > > > > > > My first problem was trying to figure out what should remain Ruby > > > code > > > > and what should be moved out to C. For example, if I opened the file > > > > that contained binary data in Ruby, how could I "get" to that data > > > > using a FILE pointer in C? Or should I just pass the filename to the > > > > C extension? > > > > > > > You can do either. IMO it depends on the layout of the file. If your > > > reading line by line you can do this easily using the rb_io_* functions > > > found in intern.h. If your going to be moving the file position > > > around, using fgetc/ungetc, or reading into C structs it may be easier > > > to use the stdio functions directly. > > > > > > -Charlie > > > > So, if I have a IO object in Ruby, how could I use C's stdio functions > > on it? You can't. > > And how could I have figured it out without asking the mailing > > list? :-) Cuz I'm sure I'll have lots more questions. > > Although you could get the FILE ptr from the Ruby IO Object it is definately not a good idea. Also the next version of Ruby will not use stdio at all, so you code will break. So basically you can do one or the other - use a Ruby IO Object (and the rb_io_* methods) or use fopen and friends. > > Thanks, > > Joe > > > And to expand the question... > > I'm using the GD library to create the image. I'm creating the image > by reading binary data from a file and looping through some > predetermined width and height and setting each pixel of the picture > based on the data from the file. > > Which parts of this should go in the C extension and which parts > should stay Ruby? I'm really scratching my head over this one. > > Thanks, > Joe Seems like you already decided the looping should be done in C. Seems like you have two options: 1) Open the file and read a buffer (String) in Ruby using IO#read and pass it to your C extension which then loops through the buffer and does the pixel stuff. 2) Open the file and read a buffer in C, then loop though it. (Probably should use fread() to read the buffer since there is no rb_io_read function, but if you wanted you could use a Ruby IO object and rb_funcall.) Option one seems more modular, but it sounds like the size of the buffer and the range of the loop are coupled so maybe not. Option two will probably be faster because if you can reuse the buffer and / or declare it on the stack. -Charlie