From: ptkwt@...1.aracnet.com (Phil Tomson) Date: 2002-08-04T07:56:21+09:00 Subject: Re: embed or swig? In article <005d01c23b0f$135b6460$0300a8c0@austin.rr.com>, Hal E. Fulton wrote: >----- Original Message ----- >From: "Phil Tomson" >Newsgroups: comp.lang.ruby >To: "ruby-talk ML" >Sent: Saturday, August 03, 2002 1:35 AM >Subject: embed or swig? > > >> Then it hit me... we alreay wrap all of our C++ objects with Swig so that >> we can do unit testing in Ruby using Test::Unit so why not take it a step >> further and use Ruby to tie together all of our C++ objects. The idea >> being that instead of embedding Ruby into our C++ application we'll use >> Ruby to manipulate the objects defined by C++. All of the comutationally >> intensive stuff is already done in those C++ classes so there won't be any >> performance hit. We won't define a main() function on the C++ side, we'll >> just create the shared library from the swig wrappers and instantiate >> those objects in Ruby. > >This sounds very interesting to me... can you >explain how this actually works? > >I've never really looked at SWIG. I didn't >realize it was quite this powerful... > First take a look at Swig at: http://www.swig.org Now to explain a bit more what we're doing: We started off wanting to do unit testing of our C++ classes so I tried out Swig1.3.13 to wrap our classes. Let's say you have three classes, we'll call them Line, Polygon and Point and let's say you want to have them live in a namespace called Geo. You would define an interface file as an input to swig that would looks something like: %module Geo %{ #include "Line.h"; #include "Polygon.h"; #include "Point.h"; %} %include "Line.h"; %include "Polygon.h"; %include "Point.h"; //end of Geo.i (probably not completely right, I'm doing from memory) Now you run swig on the interface file and it generates a wrapper file which you then compile and link with the object files (Line.o,Polygon.o,Point.o). (see the Swig/Ruby docs at: http://www.swig.org/Doc1.3/Ruby.html for more details) Now from Ruby you can access the objects in the Geo module: #ruby: require 'Geo.so' lines = [] line = Geo::Line.new(0,0,5,5) lines << line lines << Geo::Line.new(5,5,8,5) lines << Geo::Line.fromPoints(Geo::Point.new(4,3),Geo::Point.new(5,4)) lines << Geo::Line.new(9,8,7,6) polygon = Geo::Polygon.new(lines) #end So we're instantiating Line, Point and Polygon objects which were really defined in C++. Swig essentially makes it easy to create C/C++ extentions. In our application we're now parsing an input file which describes some geometry and then instantiate our C++ objects all from Ruby. So as I said in my previous post, instead of having a main() function in C++ we just have a shared library that gets require'd by Ruby and we let Ruby take care of the parsing, instantiation of C++ objects and then we call some methods on those C++ objects to make them do their stuff. ....That's the 10000 foot view of what we're doing anyway. I'm thinking that I need to write an article about this methodology (actually there could be two articles - using Swig and Ruby for C++ unit testing, using Ruby to tie together C++ objects (gotta think of a better title for that one)) Phil