Using a C structure as a Perl object with XS

This page explains how to use a C structure as a Perl object in a Perl XS file. In the following example code, the object $bh is a C structure.

use warnings;
use strict;
use Mukkinese::BattleHorn;

my $bh = Mukkinese::BattleHorn->new ();
$bh->set_cost (1999);
print "The cost of your battlehorn is ", $bh->get_cost (), ".\n";

(download)

This page explains how to create the Mukkinese::BattleHorn module.

In this C header file, battlehorn_t is a C structure.

typedef struct battlehorn {
    int cost;
}
battlehorn_t;

int cost (battlehorn_t * bh);

(download)

It is used in the following C file.

#include "battlehorn.h"

int cost (battlehorn_t * bh)
{
    return bh->cost;
}

(download)

In the typemap of the XS, add a definition

battlehorn_t * T_PTROBJ
Mukkinese::BattleHorn T_PTROBJ

(download)

In the XS file, add another typedef before MODULE= . Change the two colons to underscores:

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

#include "battlehorn.h"

typedef battlehorn_t * Mukkinese__BattleHorn;

MODULE = Mukkinese::BattleHorn PACKAGE = Mukkinese::BattleHorn

PROTOTYPES: ENABLE

Mukkinese::BattleHorn
new (char * class, ...)
CODE:
        RETVAL = calloc (1, sizeof (battlehorn_t));
        if (! RETVAL) {
                Perl_croak ("No memory for %s", class);
        }
OUTPUT:
        RETVAL

void
DESTROY (bh)
        Mukkinese::BattleHorn bh;
CODE:
        free (bh);

void
set_cost (bh, cost)
        Mukkinese::BattleHorn bh;
        int cost;
CODE:
        bh->cost = cost;

int
get_cost (bh)
        Mukkinese::BattleHorn bh;
CODE:
        RETVAL = cost (bh);
OUTPUT:
        RETVAL

# Local variables:
# mode: c
# End:

(download)

The Perl module corresponding to it is

package Mukkinese::BattleHorn;
use XSLoader;
our $VERSION='1.0';
XSLoader::load 'Mukkinese::BattleHorn', $VERSION;
1;

(download)

The Makefile.PL for this example is

use warnings;
use strict;
use ExtUtils::MakeMaker;
WriteMakefile (
    NAME => 'Mukkinese::BattleHorn',
    VERSION_FROM => 'BattleHorn.pm',
    OBJECT => 'BattleHorn.o battlehorn.o',
);

(download)

To run this without installing, download the files, use perl Makefile.PL and make to build the module, and then run the test program with

perl -I blib/lib -I blib/arch battlehorn.pl 

Copyright © Ben Bullock 2009-2017. All rights reserved. For comments, questions, and corrections, please email Ben Bullock (benkasminbullock@gmail.com). / Privacy / Disclaimer