From: ahoward Date: 2003-02-21T23:22:06+09:00 Subject: Re: Ruby-swig for C struct plus methods On Fri, 21 Feb 2003, Bil Kleb wrote: > We've been playing with testing a C-code via Ruby and testunit, > wrapping the C by hand. We've just recently tried using SWIG to > automate the wrapping, but so far we haven't found the right combination > for our situation. > > We have C-routines that look a lot like a C++ class, i.e., a struct > definition followed by associated methods where each method takes a > pointer to the associated struct as the first argument. > > The trouble is the C SWIG generator creates a class for the struct > and global module methods for the functions, and we've been unable > to figure out how to get the methods mixed into the class created by > the struct. > > Then again, maybe we're asking too much from SWIG's C-interface generator > and we should just embrace the latent object-oriented design of our curent > C code and migrate it to C++? > > Note: we'd also like to do some prototyping and possibly high-level > orchestration in Ruby in addition to merely using the test framework. i do not have any swig advice, but i have done exactly this by hand : * designed simple C 'classes' with member functions (f pointers) * map this onto a simple ruby class * use ruby classes for testing one thing i thought i'd point out is that i follow this 'pattern' for my C 'classes' foo.h -------- /* this is our class 'foo' */ struct foo { /* public */ /* methods */ int (*m) (struct foo *self, int x); /* data */ int x; /* private */ /* methods */ int (*_m) (struct foo *self, int x); /* data */ int _x; }; /* public class 'foo' methods */ int foo_new (struct foo **object, int n, ...); int foo_delete (struct foo **object); /* public class data */ int foo_x = 42; -------- foo.c -------- /* public class 'foo' methods */ int foo_new (struct foo **object, int n, ...) { struct foo *self = *object; self = malloc(n); ... self->m = m; self->_m = _m; ... self->x = foo_x; self->_x = _foo_x; } int foo_delete (struct foo **object) { struct foo *self = *object; ... free (self); ... self = NULL; } /* private class data - note that they are NOT exportable */ static int _foo_x = 42; /* instance methods - note that they are NOT exportable */ /* public */ static int m (struct foo *self, int x) { ... } /* private */ static int _m (struct foo *self, int x) { ... } -------- which exports nothing non-essential into the header file. in particular the member methods should be static which would at least prevent SWIG from exporting them! following this pattern the mapping to ruby is so easy i simply do it by hand - err, guess i should be looking a SWIG too! i would be very interested to hear your final methodology and experience with SWIG as i find that developing in C first, then wrapping in ruby to be infinitely more eloquent and easy to test than developing in C--. ;-) -a -- ==================================== | Ara Howard | NOAA Forecast Systems Laboratory | Information and Technology Services | Data Systems Group | R/FST 325 Broadway | Boulder, CO 80305-3328 | Email: ahoward@fsl.noaa.gov | Phone: 303-497-7238 | Fax: 303-497-7259 ====================================