xsubpp 2.000 alpha 1 ==================== WARNING: This documentation is *very* incomplete. Objective. ========== My goal was to allow easy access to real C data structures for Perl External extensions. This included both the ability to access global variables exported by C libraries and the ability to to make use of more complex C data types in xsub parameters and as variables. All of these goals have been achieved (partially at least). As someone recently said on this list (Tim, I think), make it easy to do the simple things, and make it possible to do the complex things. I'll let you be the judge of that. With that in mind I have attempted to make the default interface to this new stuff look as much like the original C as possible. Interfacing to simple data types ================================ Firstly there are the cases where you just want to interface to a simple (int, char*, ...) global variable in some external C library, an integer version number say. The typemap file already contains all the information necessary to read and write most non-complex data structures. So for this type of interface I wanted to be able to write something like int Year in the .xs file and let xsubpp create a read/write interface to the C variable which can be accessed from Perl like this $Year = 1995 ; ... if ($Year > 2000) ... This has been achieved using the suggestion made by Larry (last year I think) of associating an index with each C variable and tie'ing the Perl scalar to a package which can work out the correspondence between the index and the real C variable. Interface to Complex Data structures ==================================== The second case (and my main reason for extending xsubpp) is interfacing to complex C data structures (i.e. structures, unions, arrays). As there is no real support for these in xsubpp it was necessary to design some. As with the simple data types I wanted to keep the default definition of the data structures simple and as close to C as possible. .xs interface ============= An XS file is currently split into a number of sections. Everything up to the first MODULE line is written the the C file verbatim. Thereafter the file contains a sequence of MODULE sections, each of which contain a number of XSUB definitions. In order to keep with the spirit of this structure and remain backward compatible with existing code I have defined a number of new sub-sections for the MODULE section. The list below shows the new sub-sections. XSUB TYPE HASH TYPE ARRAY TYPE SCALAR VAR If no sub-section is specified XSUB will be assumed. This will allow existing .xs files to be parsed with the new xsubpp. XSUB ----- Used to define xsubs. No change from the original xsubpp. TYPE HASH --------- Creates a type definition for a C structure/union. The struct/union definition is 'similar' to the equivalent C definition. Consider the example below. MODULE = Data PACKAGE = Data TYPE HASH struct fred int alpha short beta The first line of the data type definition *must* correspond to the C definition for the data type. So in this case struct fred is the C data type we are creating an interface to. To make it a bit easier to use existing C structure definitions xsubpp will remove any trailing semicolons, and also get rid of any '{' or '}' it finds. So struct fred can be written like this: struct fred { int alpha ; short beta ; } ; As with XSUB's it is possible to tailor the default behavior of the interface. TYPE HASH struct fred int alpha short beta FETCH: alpha ... code STORE: beta ... code ACCESS: ro alpha ACCESS: wo alpha NOTE: The structure/union must be defined *completely* before any of the tailoring code is introduced. So FETCH: allows you to modify the default read interface for an individual element of the structure/union. STORE: does the same for the write interface. ACCESS: allows you to make individual elements of the structure/union read-only or write-only. In addition to FETCH, STORE and ACCESS, you have SIZEOF:, ADDRESSOF:, LENGTHOF:, CLONE:, NEW: and DESTROY:. These methods apply to the complete data type and not individual elements. Note that not all of these last methods have been fully implemented yet. TYPE ARRAY ---------- Creates a type definition for an array. MODULE = Data PACKAGE = Data TYPE ARRAY int myarray [100] ; Works the same way as the TYPE HASH except the definition of the array takes only 1 line. TYPE SCALAR ------------ Creates a type definition for a scalar. I'm not sure if this section will be kept. VAR --- This sub-section creates an interface to *existing* C variables. Note that the C variable is assumed to exist already. This sub-section only creates the Perl interface to the variable. There are currently two variations with this sub-section. The first (which might or might not get dropped) is interfacing to simple data types like int and long. In these cases a definition like this VAR int fred ; will create a Perl interface which will allow 'fred' to be accessed directly, thus: $fred = 1 ; $b = $fred ; The second variation is interfacing to a type defined in one of the TYPE * sub-sections. In this case a definition like this: VAR struct fred MyFred ; will create a Perl interface which is accessed via a reference, thus: $MyFred->{alpha} = 2 ; $x = $MyFred->{beta} + 1 ; TYPEMAP Interface ================= It was necessary to extend the TYPEMAP file a bit. As with the .xs file, I have tried to keep the file backward compatible with the existing file. Both the INPUT and OUTPUT sections remain unchanged. The TYPEMAP section has been extended to take an optional parameter thus. TYPEMAP TYPEMAP XSUB TYPEMAP HASH TYPEMAP ARRAY TYPEMAP SCALAR The first two, TYPEMAP and TYPEMAP XSUB are equivalent. TYPEMAP HASH is used for the elements of structures/unions. When xsubpp is resolving a type for a structure element it will first check TYPEMAP HASH. If there is an entry it will be used. If not the TYPEMAP XSUB will be checked. This has been done because the existing typemap entries for quite a few types are fine for accessing the structure elements. The type resolution is the same with TYPEMAP ARRAY and TYPEMAP SCALAR. Perl Interface =============== The Perl interface to any data type defined in a TYPE * section in the .xs file is through a reference. A type (e.g. the struct fred shown above) can be instantiated thus $a = new Data::fred ; and read from /write to thus $a->{alpha} = 33 ; $y = $a->{beta} ; Similarly for an array $b = new Data::myarray ; $b->[3] = 5 ; $x = $b->[0] ; Other Methods ------------- Each of the complex data structure types has a number of methods defined for it. sizeof lengthof addressof clone The meaning of each of these is what you would expect in C (except clone, which is intended to create a duplicate of the complete data structure). So $b->lengthof is 100. What still needs to be done. ============================ * references, destroy, tailoring of new/addressof - references mostly work - destroy has been ignored for now * move util functions into core Perl? * tidy up the 'new' function. * naming - should it be MODULE::type ? * test harness for both the new stuff *and* existing xsubpp functionality -- started Paul Marquess