For this kind of work you might find SWIG easier to use:

    http://www.swig.org/
    http://www.swig.org/Doc1.1/HTML/Perl5.html

I haven't used it myself for years, but I'd certainly consider it
carefully for any project where I needed access to structure members.

Tim.

On Wed, Mar 19, 2008 at 06:23:34PM -0700, Michael G Schwern wrote:
> I have a project to make the functions of a C program available to Perl for 
> unit testing purposes.  A lot of them use structs like so...
>
> typedef struct
> { 
>   char *config_file_name; 
>   char *input_file_name; 
>   char *time_str;
>   int test_mode;             /* flag set from command line or config value 
> */ 
>   int mail_input;            /* flag set from command line */ 
>   int debug;                 /* flag set from command line */ 
>   int save;                  /* flag set from command line */ 
>   GHashTable *forw_hash;     /* stores email addresses for forward messages */
>
>   ...and so on...
>
> } options_struct_t
>
> Note the additional complication of the non-standard GHashTable type (from 
> Gnome).
>
> They pass them into functions to be modified, prototyped like this:
>
> void set_option(
>     options_struct_t *options,
>     char *key,
>     char *val,
> );
>
> I'm having difficulty figuring out how best to map this to Perl, both 
> conceptually and the XS details.  If I was making it Perlish I might have 
> an options object:
>
>       $options->set($key, $val);
>
> but I'm hesitant to change the interface so radically, the point is to test 
> the C code.  I'm going with a more literal translation:
>
>               my $opts = {};
>       set_option( $opts, foo => $foo );
>       set_option( $opts, bar => $bar );
>
> The real issue is how best to translate between the struct and Perl.  Using 
> a hash, like I do above, means I have to translate key element of the 
> struct to a hash key and back.
>
> void 
> _hv2options(HV *hash, options_struct_t *options) { 
>     SV ** hash_val; 
>
>
>     if( hash_val = hv_fetchs( hash, "mail_input", 0 ) ) 
>         options->mail_input                 = SvIV(*hash_val); 
>
>
>     if( hash_val = hv_fetchs( hash, "input_file_name", 0 ) ) 
>         options->input_file_name            = SvPV_nolen(*hash_val); 
>
>       ...and so on...
> } 
>
>
>
>
> void 
> _options2hv(options_struct_t *options, HV *hash) { 
>     hv_stores(hash, "mail_input",       newSViv( options->mail_input )); 
>     hv_stores(hash, "input_file_name",  newSVpv( options->input_file_name, 0 
> ));
>
>       ...and so on...
> } 
>
> As you can imagine, this rapidly gets tiresome.  Also I'm a crappy C 
> programmer.
>
> I know there's something to make C structs act like objects, but I'm having 
> trouble wrapping my head around it.  I have this vague feeling that there's 
> a way to make Perl auto-generate accessors to each struct element but I'm 
> not sure how.
>
> Any help?
>
> Complicating this problem is that h2xs will not run over this code, it gets 
> lost in the twisty maze of includes and drags the CPU with it down in a 
> drunken spiral.
>
>
> -- 
> 125. Two drink limit does not mean two kinds of drinks.
>     -- The 213 Things Skippy Is No Longer Allowed To Do In The U.S. Army
>            http://skippyslist.com/list/

Reply via email to