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/