Here is an update on the status of Inline::Struct.
The first working version is finished, but will not be available until
Brian returns, because it requires a patch to Inline.pm. That patch is
included at the bottom for the more curious inliners.
Inline::Struct will probably be distributed with the core Inline package.
SYNOPSIS:
use Inline C => <<'END', STRUCTS => ['Foo'];
struct Foo {
int inum;
double dnum;
char *str;
};
typedef struct Foo Foo;
END
my $o = new Inline::Struct::Foo;
$o->inum(10);
$o->dnum(3.1415);
$o->str('Wazzup?');
my %fields = %{$o->_HASH};
my @keys = @{$o->_KEYS};
my @fields = @{$o->_ARRAY};
package Inline::Struct::Foo;
sub Print {
my $o = shift;
print "Foo {\n", (join "\n", map { $o->$_() } $o->_KEYS), "}\n";
}
FEATURES
o Adds two new configuration options to C and C++:
STRUCTS:
Takes either the name of a struct, or an array ref containing a list
of structs to bind.
NOSTRUCTS:
Suppresses binding of structs to Perl.
o In the absence of STRUCTS and NOSTRUCTS, any structs will automatically
be bound to Perl. They will be put in Inline::Struct::<struct name>.
o Automatically generates three things for bound structs:
- a Perl class with the following autogenerated methods:
new -- if no arguments, creates a zero'd struct.
-- elsif the arguments equal the number of fields, assigns the
arguments to the fields in the struct order.
-- elsif the number of args is divisible by 2, assume it's a
"hash" assignment: new Foo(str => 'neil', inum => 10). Any
unassigned items remain zero'd.
-- else croak.
DESTROY -- frees the C structure, iff it was allocated by Perl.
_HASH -- returns a hash ref containing the field/value pairs.
_ARRAY -- returns an array ref containing the field values. Struct
order.
_KEYS -- returns an array ref containing the field names. Struct
order.
In addition, each field generates a method of the same name. If you
pass it no arguments, it returns the value of that field. If you pass
it an argument, it sets that field and returns the object, so that
you can chain such assignments: $o->inum(10)->dnum(3.1415);
- typemaps: For each struct, it generates a typemap so that you can
pass struct objects back into Perl from C functions, or vice versa.
- convenience macros:
INLINE_STRUCT_NEW(target, type) -- allocate a new <type>
INLINE_STRUCT_FIELDS(type) -- returns number of fields in <type>
INLINE_STRUCT_INIT_LIST(target, type) -- inits the target from ST()
INLINE_STRUCT_INIT_HASH(target, type) -- inits the target from ST()
INLINE_STRUCT_ARRAY(src, targ, type) -- creates an array from src
INLINE_STRUCT_HASH(src, targ, type) -- creates a hash from src
INLINE_STRUCT_KEYS(src, targ, type) -- creates a key list from src
INLINE_STRUCT_GIVE(src, type) -- "give" a C struct to Perl for memory
handling. Once this is done, you are forbidden from freeing the
memory used by the struct, since Perl will also try to free it. If
you do not give the struct to Perl, you can still pass the struct
to Perl subs, but you will be responsible for cleaning it up
yourself. Note that there is no corresponding INLINE_STRUCT_TAKE(),
because that could leave Perl scalars lying around which still
think they refer to a valid C struct, but that struct has been
deleted by the overzealous C programmer. This macro may be
introduced in the future.
Feature requests? Interface enhancements or suggestions? Let me know!
Later,
Neil
--8<--Patch to Inline.pm--8<--
@@ -428,7 +428,7 @@
next if $mod eq 'Files';
($mod) = $mod =~ /(.*)/ if UNTAINT;
eval "require
Inline::$mod;\$register=&Inline::${mod}::register";
- croak usage_register($mod, $@) if $@;
+ next if $@;
my $language = $register->{language}
or croak usage_register($mod);
for (@{$register->{aliases}}) {
Reason for patch:
Inline.pm currently croaks whenever it finds an Inline module which does
not support the Inline API. Inline::Struct and Inline::Files are two such
modules. Note that Inline::Files has been special cased. This is not
correct behaviour, which is to ignore non-Inline modules, rather than
croak.
--8<--End of patch--8<--