Worked that on a bit :
- .cpp file is generated by XS directly. This is handled by the makefile
- xs makes function mapping really easy. To map a C function a quest function, simply put the prototype in the cperl.xs file
- more complex functions (like those that refer to instances, not C functions), require XS writting.
Here's what's added to the makefile :
Code:
PERLMOD=/usr/lib/perl5/5.8.0/ExtUtils/
XSUBPP=perl -MExtUtils::Miniperl /usr/bin/xsubpp -C++ -prototypes -nolinenumbers -typemap $(PERLMOD)/typemap
%.cpp: %.xs
$(XSUBPP) -typemap EQEMu.typemap $< > $@
of course you need to add the cperl.o to your SF files.
now here is the cperl.xs file :
Code:
#include "masterentity.h"
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
// more definitions for the C functions allowed here
const char *getItemName(unsigned itemid)
{
const Item_Struct* item = NULL;
item = database.GetItem(itemid);
if (item)
return item->Name;
else
return NULL;
}
MODULE = EQEMu PACKAGE=eqemu
const char *
getItemName(unsigned itemid);
In the above example, a new function was created, and mapped to perl. It's a bit long because it's a new function. Else, the function body does not need to be in this file. Only the part after the MODULE keyword is to change.
i also added a EQEMu.typename file, that is empty atm, to allow mapping of C types to perl types. Leave empty for now.
There are several possibilities with XS, that allow to really tweak the interface between C and Perl. Full descriptions are :
a tutorial
reference of XS constructs
Note, as compared to m0ni9's work :
- changed MODULE name from qc to EQEMu. Less risks to cope with an existing or new perl module
- changed package name from
quest to
eqemu. This is important, because in perl code, you are going to call both subs :
Code:
sub EVENT_ITEM {
quest::say("Ooh, a " . eqemu::getItemName($item1) . "! Here's your reward!");
quest::givecash(5,0,0,0);
quest::exp(100);
}
The quests::thing() is a command, pushed on the queue, that the zone server will process
after the perl EVENT subroutine is done
The eqemu::thing() is called
immediatly in perl subroutine. Thus it is effective to write :
Code:
my $itemname=eqemu::getItemName($item1);
I would not explain more about XS now (because i'm just not able to, i discovered it thanks to mOoni9

). Just some info to add more functions :
- if function exists, simply put prototype in the second part. Insert headers required by function prototypes on top of file (near #include "masterentity.h")
- append prototypes in second part of the file, after the MODULE construct. You need not to repeat the MODULE line, just add prototypes
- XS is touchy about indentation. To write a prototype : return type must be on first line, alone. It must have no leading spaces. Function name and args can be ANSI style, or trditionnal C style. In latter case, indent parameter declaration, that must have leading spaces ; You'll get more details
there
happy coding ! Thanks m0oni9 again for the pull.
p.s. This post might be edited more than a couple of times on, this is very pre-alpha
