NAME
XS::Writer - Module to write some XS for you
SYNOPSIS
# As part of your build process...
use XS::Writer;
my $writer = XS::Writer->new(
package => 'Some::Employee',
# defines the employee struct
include => '#include "employee.h"',
);
$writer->struct(<<'END');
typedef struct employee {
char * name;
double salary;
int id;
};
END
# This will generate lib/Some/Employee_struct.xsi
# and lib/Some/Employee_struct.h
$writer->write_xs;
# Then in lib/Some/Employee.xs
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
MODULE = Some::Employee PACKAGE = Some::Employee
INCLUDE: Employee_struct.xsi
...any other XS you like...
# You must add this to lib/Some/typemap
TYPEMAP
Some::Employee T_PTROBJ
# And finally in lib/Some/Employee.pm
package Some::Employee;
our $VERSION = 1.23;
use XSLoader;
XSLoader::load __PACKAGE__, $VERSION;
# And you will be able to do
use Some::Employee;
my $employee = Some::Employee->new;
$employee->name("Yarrow Hock");
DESCRIPTION
I went nuts trying to figure out how to map structs into perl. I finally figured it out and I never want anyone else to have to go through that. I also wanted the process to remain transparent, many of the XS writing modules are themselves almost as complicated as XS itself.
This module helps you write XS by taking care of some of the rote things for you. Right now it just makes structs available as objects, writing a constructor and accessors. It's designed to be fairly transparent but you still need to understand some XS.
The instructions are meant for Module::Build. Adapt as necessary for MakeMaker.
Example
See t/Some-Employee in the source tree for an example.
Stability
It's not. I'm writing this to fit my own needs and it's likely to change as my knowledge of XS changes. Also the XS it generates probably isn't the best in the universe. Patches welcome.
Methods
new
my $writer = XS::Writer->new( %args );
Setup a new writer. Arguments are...
package (required) The package to write your XS into.
xs_file (optional) Where to write the XS file. Defaults to
lib/Your/Package_struct.xs
include (optional) Any extra code to include
struct
$writer->struct($typedef);
The typedef for the struct you'd like to write a class around.
The C parser isn't too sophisticated.
type_accessor
$writer->type_accessor($type, $xs);
XS::Writer will deal with simple types, but you will have to supply code for anything beyond that.
Here's an example for an accessor to elements with the 'double' type.
$writer->type_accessor('double', <<'END_XS');
$type
$accessor( $class self, ... )
CODE:
if( items > 1 ) /* setting */
self->$key = SvNV(ST(1));
RETVAL = self->$key;
OUTPUT:
RETVAL
END_XS
Variables should be used in place of hard coding.
$type same as the $type you gave
$accessor name of the accessor function
$class type of the struct
$key the element on the struct being accessed
make_xs
my $xs = $self->make_xs;
Generates the XS code.
write_xs
$writer->write_xs;
Writes the XS to $writer->xs_file.
AUTHOR
Michael G Schwern <schwern@pobox.com>
LICENSE
Copyright 2008 by Michael G Schwern <schwern@pobox.com>.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
See http://dev.perl.org/licenses
THANKS
Thanks to...
Tom Heady for answering my cry for XS help and showing me how to do struct accessors.
Simon Cozens for "Embedding and Extending Perl"