Re: XS help

[email protected] (Tim Bunce)
Newsgroups perl.makemaker
Message-ID <[email protected]>
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/
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.