ЭЛЕКТРОННАЯ БИБЛИОТЕКА КОАПП
Сборники Художественной, Технической, Справочной, Английской, Нормативной, Исторической, и др. литературы.



19.4 Adding Extensions

In the preceding pages, we created C applications that made calls to the Perl library, parsed scripts, and sent data between Perl and C space. In the meantime, we studiously avoided the issue of extensions, if you recall, by passing NULL to perl_parse instead of the address of an initialization subroutine. This means that we could not make use of any C-based extensions in the scripts, even common ones such as Socket and SDBM - clearly an unacceptable solution for real applications.

In this section, we learn a simple way of making standard and custom extensions accessible to the embedded Perl interpreter.

The initialization subroutine, which we will refer to as xs_init, is responsible for calling the initialization routines for all statically linked extensions. If you prefer dynamic loading, xs_init simply needs to initialize the built-in dynamic loader.

Instead of handcoding xs_init, we rely on a very convenient module called ExtUtils::Embed to produce it for us. This module is packaged with the Perl distribution, and is used like this:

perl -MExtUtils::Embed -e xsinit -- -o xsinit.c -std IO::Socket DBI

The -M option is identical to saying "use ExtUtils::Embed;". This invocation produces a file called xsinit.c with a publicly available function called xs_init, which in turn contains the code to initialize all the standard modules (thanks to the -std argument), and the two custom modules, IO::Socket and DBI.

How does this module know what is standard or whether we want these packages linked statically or dynamically? Well, when Perl is compiled and installed, it keeps an inventory of all statically linked extensions (if any) and the parameters supplied to the configure script, such as compilation and linking options, location of the Perl installation, and so on. This inventory is kept in a module called Config.pm. The Embed module taps this information to produce the right set of initializations. In addition, Embed can be asked to print out the compilation and linking options, and we can leverage it on the command line as follows:

% cc -c xsinit.c         `perl -MExtUtils::Embed -e ccopts`
% cc -c ex.c             `perl -MExtUtils::Embed -e ccopts`
% cc -o ex ex.o xsinit.o `perl -MExtUtils::Embed -e ldopts`

In addition to sparing us the bother of hand-writing the initialization code, and filling in the appropriate compiler and linker command-line options, this module makes it simple to drop in other extensions in the future. Of course, if the embedded interpreter is set up for dynamic loading, there is no need to recreate xsinit.c, because it only contains one call to initialize the dynamic loader.