1. Perl
  2. XS
  3. here

Create an XS module

A C language (or C ++) function created so that it can be called from Perl is called an extension. Generally, it seems that it is often collectively called XS, so I will call it XS. I would like to write the flow from creating an XS module to creating a module to call from Perl. The work flow is as follows. Twice

  1. Creating an XS file
  2. Generate C language source file from XS file
  3. Generate a dynamic link library from a C language source file
  4. Creating a Perl module to call a dynamic link library

If you don't understand C language at all, we offer the following courses.

Flow of XS module creation

Create XS file

The first is to create an XS file. The extension is (.xs). The file contains the C language source code and XSUB. XSUB is written in the XS language and is very similar to C functions. Think of it as writing a C language function in substance.

# C language section (such as loading a library)
...

# XSUB section (written in XS language)
Return value
Function name
Mold
Processing (the processing part is C language)

Return value
Function name
Mold
Processing (the processing part is C language)

Generate C language source file from XS file

Convert the XS file to a C language source file using a program called xsubpp. At this time, a definition called typemap is used to convert the types of Perl in C language to each other. The typemap is included in the ExtUtils::MakeMaker module.

                        xsubpp
XS file + typemap - -- -- -- ->C language source file

With the XS language, you often don't have to write the C and Perl type conversion process yourself. xsubpp will refer to the typemap file and automatically add the conversion process. You can also write the conversion process yourself or extend the typemap.

Dynamic link library generation

C language source files are compiled using a C compiler (such as gcc) and converted to a dynamic link library (such as * .so).

                       C compiler
C language source file - -- -- -- -- -- ->Dynamic link library

A dynamic link library is a library that can be called dynamically. Normally, the library is created in this format.

Creating a Perl module to call a dynamic link library

Finally, create a Perl module to call the dynamic link library. A module called XSLoader allows you to load a dynamic link library and call the functions written in the dynamic link library as Perl functions.

package Your Package;
use XSLoader;

XSLoader::load'YourPackage', $YourPackage::VERSION;

XSLoader loads the dynamic link library under the directory auto in the search path contained in @INC. The dynamic link library has the extension dll on Windows and so on Linux.

To actually create an XS module

Make sure to remember the above flow. When creating an XS module, the flow is the same no matter what you create. All the programmer needs to focus on is creating the XS file. Most of the rest of the work can be automated, so creating a simple XS module is not difficult.

However, generally speaking, creating an XS module is difficult. This is because it requires a large amount of not-so-easy peripheral knowledge such as "XS language", "typemap", "Perl API", "make", "C compiler", "linker", and "ExtUtils::MakeMaker". Therefore, it is important to first grasp the basics firmly and then acquire peripheral knowledge.

Create XS module - h2xs command

Use the command h2xs to create an XS module.

# h2xs command
h2xs [optional] C header file

This command originally creates an XS module from a C header file.

That's why it's named h2xs (that is, it means "C header file to XS"), but it can also be used to simply create a template for the XS module.

Run h2xs with the following options to create an XS module.

# Creating an XS module
h2xs -A -n SomeModule

"-A" is an option that omits the auto-loading function. When creating an XS module, the autoloading function is usually omitted. Specify the name of the XS module with "-n".

This command creates a directory named "SomeModule" in the current directory.

Module configuration

The created module has the following structure.

Changes
SomeModule.xs
lib - SomeModule.pm
Makefile.PL
MANIFEST
ppport.h
README
t - SomeModule.t

I would like to briefly explain the role of each file.

  • Changes - Describes the change history of the module.
  • SomeModule.xs - XS file. Write XSUB in XS language.
  • lib - Contains Perl modules. This module calls a library written in C language.
  • Makefile.PL - A Perl script for generating makefiles for compiling C source files, installing modules, etc.
  • Describes the files required when distributing the MANIFEST -XS module.
  • ppport.h - C header file for compatibility with older Perl.
  • README-A brief description of the module.
  • t - Stores test scripts.

The most important of these is "SomeModule.xs". When writing the simplest XS, all you need to write is "SomeModule.xs". To do something a little difficult, you need to learn how to write Makefile.PL. It may be added to the Perl module file included under lib. You also need to write the Changes, MANIFEST, and README when packaging for distribution. You will also need to write a test script.

How to write Makefile.PL is explained in detail below.

XS file template

Now try opening SomeModule.xs first. The following template should be generated.

# include "EXTERN.h"
# include "perl.h"
# include "XSUB.h"

# include "ppport.h"


MODULE = SomeModule PACKAGE = SomeModule

You can write C language at the beginning of the XS file. "#Include" EXTERN.h "" is a C language description. For those who have never written C language, I will explain a little. "#Include" is for including other files into the source code. In C language, instructions starting with # are called directives and are instructions for the preprocessor. A preprocessor is a program that makes changes to the source code according to the directives before compiling the source code.

# include "EXTERN.h"

The description means that the C language header file EXTERN.h is included in the source code.

Files with the extension ".h" are C header files. A header file is a file that describes C language function declarations and macro definitions. You need to include it if you want to use the function written in the header in the C language source code.

I will briefly explain the C language header file required when writing an XS file.

  • EXTERN.h - Perl Global VariableHeader file required to refer to the number
  • perl.h - Perl header file
  • XSUB.h - Header file for XSUB
  • ppport.h - Header file to absorb API differences between Perl versions

The description in XS language starts from the following description.

MODULE = SomeModule PACKAGE = SomeModule

MODULE is used to specify the beginning of the XS language and the namespace of the function to be defined. Please note that this is different from the Perl package. Originally, C language is a language that does not have a namespace. If you had defined a function with a simple name, you would be in conflict. You will define a function called XSUB in the XS file, but the XSUB function name can be simple. For example, if you have a function that doubles a number, you could name it twice. However, if you use this as it is in C language, name conflicts will occur. So this function named twice will be replaced with the name "XS_SomeModule_twice" when processed by xsubpp. MODULE is needed to provide a non-collision mechanism.

PACKAGE is the Perl package name. In other words, the following correspondence can be made between Perl and C language functions by describing MODULE and PACKAGE. Creating such a correspondence so that Perl can call a C language function is called bootstrap.

Perl C language
SomeModule::twice - ->XS_SomeModule_twice

XSUB description

From here, it is the part that describes the XS language. Let's write XSUB using the XS language. XSUB is a description of a function using the XS language, which is very similar to a function in the C language. Below is a function that doubles the received integer.

void
twice (...)
  PPCODE:
{
  // Check the number of arguments
  if (items != 1) {
    croak ("Usage twice (x)");
  }
  // Convert Perl scalar to int. "ST (0)" is the first argument
  int x = SvIV (ST (0));
  
  // Calculate twice
  int x2 = x * 2;
  
  // Convert int to Perl SV and set it as return value. XPUSHs stacks one return value.
  XPUSHs (sv_2mortal (newSViv (x2)));
  
  // Specify the number of return values and return
  XSRETURN (1);
}

Since the number of arguments is assigned to the variable called items, it can be used for checking. You can use a function called croak to print an error message and exit the program.

What you have to write in XS is the work of type conversion. Converts the Perl type received as an argument to the C language type. Then, it processes in C language and converts the C language type to Perl type again. Type conversion will be explained in detail later.

Also, let's just remember the following shapes.

void
Function name (...)
  PPCODE:
{
  
}

The Perl types in XS are explained in detail below, so please refer to them.

Compile and run

As explained so far, in order to use it from a Perl module, it was necessary to process the XS file with xsubpp, compile the C language source file, and create a dynamic link library. However, this process can be automated by a program called make. Makefile.PL will generate a makefile that automates this task. So just run the following command:

# Generate makefile
perl Makefile.PL

# xsubpp processing and compilation
make

If it does not succeed, there may be a mistake in the XS language. Once this is done, a directory called blib will be created that contains the dynamic link library and Perl modules.

Let's write a script that calls the module. Create a file called test.pl in the same directory where the XS file is located.

# test.pl
use SomeModule;
print SomeModule::twice (2);

You can run this script as follows: In order to load a module for blib, you need to load a module called blib with the -M option.

# Execute a function written in C language
perl -Mblib test.pl

The output result is as follows.

Four

This completes the basics of XS. If you arrange this, you can apply XS.

Related Informatrion