View Single Post
  #10  
Old 04-26-2004, 08:41 PM
smogo
Discordant
 
Join Date: Jan 2004
Location: 47
Posts: 339
Default

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
__________________
EQEMu Quest Repository is down until something new :(
Reply With Quote