home *** CD-ROM | disk | FTP | other *** search
-
-
- =head1 Basics
-
- ExtUtils::XSBuilder is a set modules to parse C header files and create XS
- glue code and documentation out of it. Idealy this allows to "write" an
- interface to a C library without coding a line. Since no C-API is ideal,
- some adjuments are necessary most of the time. So to use this module you
- must still be familar with C and XS programming, but it removes a lot of
- stupid work and copy&paste from you. Also when the C API changes, most
- of the time you only have to rerun XSBuilder to get your new Perl API.
-
- The creation process takes place in the following steps:
-
- =over 4
-
- =item Derive a class from ExtUtils::XSBuilder::ParseSource
-
- This class must override some methods to tell XSBuilder which C header files
- to parse and some other necessary parameters. You need at least to override the
- methods C<package> to give the name of the package you want to create and
- either the method C<find_includes> and return all C header files to parse or
- the method C<include_dirs> to return a list of all directories which should
- be scanned for C header files.
-
- Of course there are more methods you can overide. See
- L<ExtUtils::XSBuilder::ParseSource> for a list of overrideable methods.
-
- =item Scan the source files
-
- If your derived class is called MyClass::ParseSource you simply start the
- source scan with
-
- perl -MMyClass::ParseSource -e 'MyClass::ParseSource->run'
-
- You may also put this into a small script to ease usage and maybe set the
- Perl libpath etc.
-
- After you run the source scan XSBuilder has created a set of tables, which
- contains the result of the parseing. If you don't have changed the defaults
- in your class, the tables are created under C<xs/tables/current> and then appended
- the name of the module you want to create as given with the method C<package>.
- There will be a C<FunctionTable.pm> which holds all the function declarations,
- a C<StructureTable.pm> which holds the structures, a C<ConstantTable.pm>, which
- contains alls constants found in the header files and a C<CallbackTable.pm>
- which contains definitions for callback types.
-
- The main reason why we not directly create XS code, but first these intermediate
- tables is, that source scanning may take some time. As we save the result, we can
- avoid rescanning the sources as long as they don't change.
-
- =item Derive a class from ExtUtils::XSBuilder::WrapXS
-
- The WarpXS class is resonsible for takeing the tables which contains the information
- about the scanned sources and from the map files (see below) and create the XS code.
- As with the ParseSource class, you have to override this call with your own implementaion,
- to tell WrapXS what to do.
-
- See L<ExtUtils::XSBuilder::WarpXS> for a list of overrideable methods.
-
- =item Create map files
-
- XSBuilder will not automaticly create XS functions for all C function and structure. You
- have to give some hints. This is basicly done via the map files. If you don't change the
- default they live under C<xs/maps>. There four map types. For each type there could
- multiple files prefixed with C<foo_>:
-
- =over 4
-
- =item foo_types.map
-
- Contains the mapping from C type to Perl classes
-
- =item foo_functions.map
-
- Contains the mapping form C functions to Perl functions. Can be used to
- reorder arguments, tell XSBuilder which arguments are actualy return values
- and in which Perl package the function will be created.
-
- =item foo_structures.map
-
- Contains the mapping from C structures to Perl classes and defines for which
- members a access methods should be created. You can also specify if you want a
- C<new> method for the class.
-
- =item foo_callbacks.map
-
- Contains the mapping form C callback functions to Perl callback functions. Can be used to
- reorder arguments, tell XSBuilder which arguments are actualy return values
- and in which Perl package the function will be created.
-
- =back
-
- For a detailed description of the format of the map files see below.
-
- To have a starting point XSBuilder is able to create default map files, which simply
- include all types, functions and structures. You can rerun this map file creation
- everytime and XSBuilder will append all items, that are not already in the maps files.
-
- First copy the _types.map file from the xsbuilder directory to your maps
- directory. This file contains some standart mapping for basic types.
-
- If your derived class is called MyClass::WarpXS you simply start the createing/update
- of the maps files with
-
- perl -MMyClass::WarpXS -e 'MyClass::WarpXS->checkmaps(" ")'
-
- The the argument to checkmaps give the character that should be at the first column
- of the new map entries. If you give no argument at all, no map files are written,
- but checkmaps will only compare what is missing. (You need to print the result somehow
- e.g. by using Data::Dumper).
- You may also put this into a small script to ease usage and maybe set the
- Perl libpath etc.
-
- After you have created your default maps, you have at least to edit the C<xs/maps/new_type.map>
- file, which contains all types that found in the sources. Simply append the class or the typename
- to the line spearated by a C<|> e.g.
-
- int | IV
- struct request_rec | Apache::RequestRec
-
- =item Create the XS files
-
- Now we can create the code. By starting
-
- perl -MMyClass::WarpXS -e 'MyClass::WarpXS->run'
-
- XSBuilder will create the XS, pm and Makefile.PL files for every module that
- is mentioned in the maps. The result is placed as a directory hierarchy under
- WrapXS. To control the content of the C<Makefile.PL> and the C<pm> file, you
- can override the methods C<makefilepl_text> and C<pm_text>. You can include
- addtional code in the XS files, by writing an include file which is included
- at the top of the XS file. This file can contain helper functions that can't
- automaticly generated. The files must be placed under the C<xs> directory,
- with the correct path and name. E.g. to have a header file included for the
- module Apache::DAV, create a file C<xs/Apache/DAV/Apache__DAV.h>. The same
- can be done for inclusion in the pm file. The name for the above example
- would be C<xs/Apache/DAV/DAV_pm>.
-
- =head1 Format of the maps files
-
- For all map files blank lines are ignored and lines starting with a C<#> are
- treaded as comments and also ignored.
-
- =head2 foo_types.map
-
- Contains the mapping from C type to Perl classes.
-
- Format is the name of the C type followed by the name of the Perl class
- or the XS type specifier, separated by a |. Example:
-
- int | IV
- struct request_rec | Apache::RequestRec
-
- If you have a Perl class with a single name namespace (e.g. Apache) you
- need to postfix it with two colons (e.g. Apache::). Structures always
- needs to be written as "struct foo", also when a typedef for "foo"
- exists.
- Addionaly you can give the id for the typemap if you need a special
- conversion and one or more other names for the struct:
-
- struct request_rec | Apache::RequestRec | T_APACHEOBJ | r
-
- an optional fivth parameter specifies that the data needs to be copied
- when assigned to a struct member and selects the way how memory is allocated:
-
- char * | PV | | | strdup
-
- The actual code for memory allocation is provided inside the structure map e.g.
-
- MALLOC=strdup:$dest = ($type)ap_pstrdup(obj -> pool, $src)
- MALLOC=malloc:ap_palloc(obj -> pool, $src, sizeof($type)) ; memcpy($dest,$src,sizeof($type))
-
- This gives two ways to allocate memory and copy the data into it. The fives
- parameter in the type map selects which of these two should be used.
- $src, $dest and $type are replaced by the source, the destionation and the type.
- C<obj> is a pointer to the C-structure.
-
-
- =head2 foo_functions.map
-
- Contains the mapping form C functions to Perl functions. Can be used to
- reorder arguments, tell XSBuilder which arguments are actualy return values
- and in which Perl package the function will be created.
-
- There are some keywords which affects all functions follwing that keyword
- until a new values for that keyword is given:
-
- =over 4
-
- =item MODULE
-
- the module name (file name) where the function should be placed in
- e.g. Apache::Connection -> Apache/Connection.{pm,xs}
-
- =item PACKAGE
-
- the package name functions belong to, defaults to MODULE
- value of 'guess' indicates that package name should be
- guessed based on first argument found that maps to a Perl class
- fallsback on the prefix (ap_ -> Apache, apr_ -> APR)
-
- =item PREFIX
-
- prefix to be stripped
- defaults to PACKAGE, converted to C name convention, e.g.
- APR::Base64 -> apr_base64_
- if the converted prefix does not match, defaults to ap_ or apr_
-
- =back
-
- The format of entries is:
-
- C function name | dispatch function name (dispatch argspec) | argspec | Perl alias
-
- Dispatch function name (the C function that is actually called) defaults
- to C function name
- if the dispatch name is just a prefix (mpxs_, MPXS_)
- the C function name is appended to it
- the return type can be specified before the C function name,
- defaults to return_type in {foo}::FunctionTable as generated by
- the ParseSource module.
- The dispatch argspec is optional, if given you can use it to pass differnt
- parameters to the dispatch function then to the xs function.
- If the function name beginns with DEFINE_ a new function is defined,
- (for defining function that are not parsed from the source). argsec
- must be given also. For the real function name the DEFINE_ is removed.
-
- The argspec defaults to arguments in {foo}::FunctionTable as generated by
- the ParseSource module
- argument types can be specified to override those in the FunctionTable
- default values can be specified, e.g. arg=default_value
-
- Example:
- ap_get_client_block | mpxs_ | r, SV *:buffer, bufsiz
- ap_setup_client_block | | r, read_policy=REQUEST_CHUNKED_ERROR
- ap_make_array | ap_make_array(r->pool, nelts, elt_size) | request_rec *:r, nelts, elt_size
-
-
- argspec of '...' indicates passthru, calling the function with
-
- (aTHX_ I32 items, SP **sp, SV **MARK)
-
- To mark an argument as return only you can prefix it with < e.g.
-
- dav_open_lockdb | | r, ro, <lockdb
-
- will be called as ($error get the return value of the C function)
-
- ($error, $lockdb) = $r -> open_lockdb (0) ;
-
- The return argument (e.g. lockdb) will always be passed by address
- to the function.
-
- the alias will be created in the current PACKAGE
-
- function names that do not begin with /^\w/ or space are skipped.
- You can prefix each function name with the following symbols:
-
- '!' => 'disabled or not yet implemented',
- '~' => 'implemented but not auto-generated',
- '-' => 'likely never be available to Perl',
- '>' => '"private" to apache',
- '?' => 'unclassified',
-
- =head2 foo_structures.map
-
- Contains the mapping from C structures to Perl classes and defines for which
- members a access methods should be created. You can also specify if you want a
- C<new> method for the class.
-
- The format looks like the following:
-
- <struct_name>
- member1
- member2
- new
- </struct_name>
-
- An optional module name can be given, so the module name specifies in which
- file the code should be placed, which the package name is determinated from
- the type map file. Example:
-
- <struct_name MODULE=My::Module>
-
- For all members that are listed here, XSBuilder will generate an access method
- to read and write it's content. If you want to name the perl access method
- different than the C member, you can write
-
- cMemberValue | member_value
-
- this will map the C<cMemberValue> structure member to the access function
- C<member_value>. Default is to use the same name in Perl as in C.
- If you give the C<new> member XSBuilder will
- create a new method for that class, which can be used to create a new instance
- of that class and initialize it with initial data.
-
- =head2 foo_callbacks.map
-
- same format as function map, but contains the callbacks
-
- =back
-
-
-