Ruby and inline C or C++

All of this talk in regards to RubyInline made me start thinking about
combining C (or C++) and Ruby. I have been working with Ruby for some
time now and it is amazing how much fun it is to program with Ruby (as
compared to my years of toil with C and C++ and forays into Perl). I
would like to use Ruby in all of my programming, but unfortunately, my
domain at work is image processing (routinely working with 3D data of
hundreds of mega-voxels) and performance is key.

To use Ruby for this domain, the only real option, of course, is to
mix Ruby and C (or C++), perhaps via SWIG or things like RubyInline or
cgenerator. And this would probably be a reasonable way to approach
it. But, what if we took things further and integrated the use
of C or C++ into Ruby itself. If we fully integrated C and C++ into
Ruby there would be no problem domain which it could not cover.

Here is what I had in mind:

module ImageProcessing
class Image
# lots of defs here
end

# Add v to each image pixel, assumes images are 8 bits/pixel
cdef void add(VALUE image, unsigned char v)
  unsigned char *pix = rb_funcall(image, rb_intern("pixel_ptr"), 0);
  long n_pixels = rb_funcall(image, rb_intern("n_pixels"), 0);
  for(long i=0; i<n_pixels; i++)
*pix++ = *pix + v
end

# Increment all pixels
def inc(image)
  add(image, 1)
end

end

But we could take this further. The code above assumes that the
Image class defines images where each pixel is a byte. What if
we want to handle images with floats (or longs or …) as pixels?
And maybe we want to define some objects in C++.
We could introduce some kind of dynamic templating (reminding me
a little of the multi-methods discussion):

class Object
def c_type
"VALUE"
end
end

class Float
def c_type
"float"
end
end

module ImageProcessing
c_class ByteImage # a c++ class
unsigned char *pixel_ptr() { … }
char *c_type() { return “ByteImage *” };
char *pixel_type() { return “unsigned char” };
end

c_class FloatImage
  float *pixel_ptr() { ... }
  char *c_type() { return "FloatImage *" };
  char *pixel_type() { return "float" };
end

# Add v to each image pixel.
# Ruby will auto-generate C++ code for this based on the types it
# sees on input (and compile and cache the result).
cdef void add(image, #{image.pixel_type} v)
  #{image.pixel_type} *pix = image->pixel_ptr();
  long n_pixels = image->n_pixels();
  for(long i=0; i<n_pixels; i++)
*pix++ = *pix + v
end

# Increment all pixels
def inc(image)
  add(image, 1)
end

end

I know I am glossing over many things, but I hope you get the idea.
By allowing one to use Ruby as sort of a templating language for
its C or C++ extensions you could do some really amazing things.
And making inline C or C++ a first class part of the Ruby language
you would erase the only negative I see in the language for some
domains–performance. Thoughts?

Derek Ney
derek @ hipgraphics . com

Is this conceptial or real?

Ruby could be used as a macro language for real ($$ professional)
code. This would make writing testing tools and prototypes easy and
viable using Ruby. No doubt, this would bring Ruby into the fold of
professional development shops much quicker.

I’m with you, I have to invent hobby projects to use Ruby at this
point. All our work is in C++. Something like this would make Ruby
immediately useful for us. Ruby’s embeded API hasn’t worked for me,
and writing extensions takes too much time to justify for the uses we
have for it.

Can this be done?

//ed

web2ed@yahoo.com (Edward Wilson) writes:

Can this be done?
yes it can be done. But how much worth is it for you? How many
customers do you expect for such a tool? I don’t think there are as
many as you believe.

Regards
Friedrich

In article 5174eed0.0209180802.5157d65@posting.google.com,

Is this conceptial or real?

Ruby could be used as a macro language for real ($$ professional)
code. This would make writing testing tools and prototypes easy and
viable using Ruby. No doubt, this would bring Ruby into the fold of
professional development shops much quicker.

I’m with you, I have to invent hobby projects to use Ruby at this
point. All our work is in C++. Something like this would make Ruby
immediately useful for us. Ruby’s embeded API hasn’t worked for me,
and writing extensions takes too much time to justify for the uses we
have for it.

As an aside (and I’m starting to sound like a broken record here, but I do
really think it’s a great tool so please forgive me) Have you tried Swig?
Swig ( http://www.swig.org) makes it easy to write C/C++ extensions
(Swig really shines with C++). Instead of embedding Ruby into your C++,
consider using Ruby as your ‘main’ to tie all of your C++ objects
together (see an earlier thread called “embed or swig” for more details).
I’ve used Ruby and Test::Unit to do C++ unit testing by
wrapping all of our C++ classes with Swig - worked great.

Phil

···

Edward Wilson web2ed@yahoo.com wrote: