KEMBAR78
March2004-CPerlRun | PDF
C Perl, C Perl Inline, C Perl XS, C Perl Guts                            Abram Hindle




                         C Perl, C Perl Inline, C Perl XS, C Perl Guts

                                            Abram Hindle

                              Victoria Perl Mongers (victoria.pm.org)

                                         abez@abez.ca

                                           March 16, 2004




Victoria.pm                                                                        1
C Perl, C Perl Inline, C Perl XS, C Perl Guts   Abram Hindle




        This Presentation
          • What am I going to Cover?
              – Inline::C

              – Perl Data Structures / Guts

              – XS




Victoria.pm                                               2
C Perl, C Perl Inline, C Perl XS, C Perl Guts                                  Abram Hindle




        This Presentation
          • What am I not going to Cover?
              – How to program in C

              – C++

              – Anything in depth

              – Magic Perl Guts

              – OO and Perl Guts

              – References and Perl Guts

              – SWIG (maybe you should take a look if you’re wrapping a lib)




Victoria.pm                                                                              3
C Perl, C Perl Inline, C Perl XS, C Perl Guts                       Abram Hindle




        Inline::C
          • What is it?
              – Write Perl Subroutines in C [1]

              – Compile and Link C into Perl

              – Embed subroutines into perl scripts and modules

              – Automatically Wrap functions based on prototypes.




Victoria.pm                                                                   4
C Perl, C Perl Inline, C Perl XS, C Perl Guts       Abram Hindle




        Inline::C
          • How do you use Inline::C?
              – use Inline C => CODE;

              – bind Inline C => CODE;
                  ∗ Dynamic generation of C code.
              –   use Inline C;
                  __END__
                  __C__
                  void cCode() {
                  }




Victoria.pm                                                   5
C Perl, C Perl Inline, C Perl XS, C Perl Guts                                        Abram Hindle




        Inline::C
          • How do you use Inline::C?
              – Inline::C parses the function prototypes and wraps them into perl.

              – Function prototypes should be in ANSI style
                ∗ return-type function-name ( type-name-pairs ) ...




Victoria.pm                                                                                    6
C Perl, C Perl Inline, C Perl XS, C Perl Guts                  Abram Hindle




        Inline::C
          • Which types are supported?
              – void → nothing

              – double → scalar

              – char * → string

              – SV* → Scalar

              – long → Scalar

              – float is not supported but you can support it




Victoria.pm                                                              7
C Perl, C Perl Inline, C Perl XS, C Perl Guts   Abram Hindle




        Inline::C
          • Example
              use Inline C;
              helloWorld();
              __END__
              __C__
              void helloWorld() {
                printf("Hello worldn");
              }




Victoria.pm                                               8
C Perl, C Perl Inline, C Perl XS, C Perl Guts   Abram Hindle




        Inline::C
          • Example
              use Inline C;
              hello(’World’);
              hello(42);
              hello(42,42);
              hello(undef);
              __END__
              __C__
              void hello(char * string) {
                printf("Hello %sn",string);
              }




Victoria.pm                                               9
C Perl, C Perl Inline, C Perl XS, C Perl Guts                                      Abram Hindle




        Inline::C
          • Example (perl guts)
              use Inline C;
              $a = "HEY";
              hello(’World’,1,42,undef,’Universe’,$a);
              __END__
              __C__
              void hello(SV* name1, ...) {
                      Inline_Stack_Vars;
                      int i = 0;
                      STRLEN count;
                      for (i = 0; i < Inline_Stack_Items; i++) {
                              char * string = SvPV(Inline_Stack_Item(i), count);
                              printf("Hello %sn",string);
                      }
              }




Victoria.pm                                                                                 10
C Perl, C Perl Inline, C Perl XS, C Perl Guts                                                  Abram Hindle




        Inline::C
          • Inline Stack Access macros
              – Inline Stack Vars       - put this macros at the top of the subroutine as it
                defines new various for Inline Stack macros to work on

              – Inline Stack Items       - how many items are on the stack

              – Inline Stack Item(i)       - get the item at index i in the stack

              – see perldoc Inline::C




Victoria.pm                                                                                             11
C Perl, C Perl Inline, C Perl XS, C Perl Guts   Abram Hindle




        Perl Guts
          • Types in C [5]
              – SV - Scalar Value

              – AV - Array Value

              – HV - Hash Value

              – IV - Integer Value *

              – UV - Unsigned Value *

              – NV - Double Value *

              – PV - String Value *

              – * return values




Victoria.pm                                              12
C Perl, C Perl Inline, C Perl XS, C Perl Guts                 Abram Hindle




        Perl Guts
          • Convert Scalars [5] ( these are macros )
              – int SvIV(SV*)

              – unsigned int SvUV(SV*)

              – double SvNV(SV*)

              – char * SvPV(SV*, STRLEN len)
               ∗ puts length in len, i is the buffer in SV*
              – char * SvPV nolen(SV*)




Victoria.pm                                                            13
C Perl, C Perl Inline, C Perl XS, C Perl Guts           Abram Hindle




        Perl Guts
          • Set scalars [5] ( these are macros )
              – void sv setiv(SV*, IV);

              – void sv setuv(SV*, UV);

              – void sv setnv(SV*, double);

              – void sv setpv(SV*, const char*);

              – void sv setpvn(SV*, const char*, int)




Victoria.pm                                                      14
C Perl, C Perl Inline, C Perl XS, C Perl Guts         Abram Hindle




        Perl Guts
          • Create scalars [5] ( these are macros )
              – SV* newSViv(IV);

              – SV* newSVuv(UV);

              – SV* newSVnv(double);

              – SV* newSVpv(const char*, int);

              – SV* newSVpvn(const char*, int);

              – SV* newSVpvf(const char*, ...);

              – SV* newSVsv(SV*);




Victoria.pm                                                    15
C Perl, C Perl Inline, C Perl XS, C Perl Guts                  Abram Hindle




        Perl Guts
          • Arrays [5]
              – Make an array
               ∗ create -    AV* newAV();

               ∗ create -    AV* av make(I32 num, SV **ptr);

              – Operations
               ∗   push - void av push(AV*, SV*);
               ∗   pop - SV* av pop(AV*);
               ∗   shift - SV* av shift(AV*);
               ∗   unshift - void av unshift(AV*, I32 num);




Victoria.pm                                                             16
C Perl, C Perl Inline, C Perl XS, C Perl Guts                    Abram Hindle




        Perl Guts
          • Arrays [5]
              – length - I32 av len(AV*);

              – fetch - SV** av fetch(AV*, I32 key, I32 lval);

              – store - SV** av store(AV*, I32 key, SV* val);

              – clear - void av clear(AV*);

              – destroy - void av undef(AV*);

              – expand - void av extend(AV*, I32 key);




Victoria.pm                                                               17
C Perl, C Perl Inline, C Perl XS, C Perl Guts                                   Abram Hindle




        Perl Guts
          • Hashes
              – HV* newHV();

              – SV** hv store(HV*, const char* key, U32 klen, SV* val, U32 hash);

              – SV** hv fetch(HV*, const char* key, U32 klen, I32 lval);

              – bool hv exists(HV*, const char* key, U32 klen);

              – SV* hv delete(HV*, const char* key, U32 klen, I32 flags);

              – void hv clear(HV*);

              – void hv undef(HV*);




Victoria.pm                                                                              18
C Perl, C Perl Inline, C Perl XS, C Perl Guts                      Abram Hindle




        Perl Guts
          • Hash iteration
              – I32 hv iterinit(HV*);

              – HE* hv iternext(HV*);

              – char* hv iterkey(HE* entry, I32* retlen);

              – SV* hv iterval(HV*, HE* entry);

              – SV* hv iternextsv(HV*, char** key, I32* retlen);




Victoria.pm                                                                 19
C Perl, C Perl Inline, C Perl XS, C Perl Guts           Abram Hindle




        Perl Guts
          • Package Vars [5]
              – SV* get sv("package::varname", TRUE);

              – AV* get av("package::varname", TRUE);

              – HV* get hv("package::varname", TRUE);




Victoria.pm                                                      20
C Perl, C Perl Inline, C Perl XS, C Perl Guts                                          Abram Hindle




        Perl Guts
          • Mortality
              – If you have temporary values such as those that are returned or used
                temporarily you want the garbage collection to handle it properley.

              – SV* sv newmortal()

              – SV* sv 2mortal(SV* sv)




Victoria.pm                                                                                     21
C Perl, C Perl Inline, C Perl XS, C Perl Guts                    Abram Hindle




        XS
          • What is XS?
              – interface description format

              – Integrate Perl and C code / libs

              – A language that is used to integrate C w/ Perl

              – Wraps C calls




Victoria.pm                                                               22
C Perl, C Perl Inline, C Perl XS, C Perl Guts                                         Abram Hindle




        XS
          • Into the fire: [4] - Some of this is ripped from the perlxstut
              – h2xs -A -n PackageName

              – Edit PackageName.xs

              – perl Makefile.PL

              – make

              – Make a test script in the PackageName directory

              – make install – only do this if your test script has problems finding
                PackageName




Victoria.pm                                                                                    23
C Perl, C Perl Inline, C Perl XS, C Perl Guts                                       Abram Hindle




        XS
          • The .xs file
              – Prototypes are done differently, see perldoc perlxs and perlxstut

              – First line, return type

              – Second line, prototype in K&R

              – Following lines, type the parameters (newline is the delimiter)

              –   int
                  strcmp(str1,str2)
                          char *str1
                          char *str2




Victoria.pm                                                                                  24
C Perl, C Perl Inline, C Perl XS, C Perl Guts                              Abram Hindle




        XS
          • Lets wrap a already existing function (add this to your .xs)
              – strcmp

              –   #include <string.h>
                  int
                  strcmp(str1,str2)
                          char *str1
                          char *str2
              – That’s it




Victoria.pm                                                                         25
C Perl, C Perl Inline, C Perl XS, C Perl Guts                  Abram Hindle




        XS
          • Lets write a new function (add this to your .xs)
              – hello

              –   void
                  hello()
                  CODE:
                  printf("Hello Worldn");
              – That’s it




Victoria.pm                                                             26
C Perl, C Perl Inline, C Perl XS, C Perl Guts                      Abram Hindle




        XS
          • Lets see our test driver (after make install)
                  #!/usr/bin/perl
                  use Hello;

                  Hello::hello();

                  print join(" ",
                                    Hello::strcmp("a","b"),
                                    Hello::strcmp("a","a"),
                                    Hello::strcmp("bbbb","aaaa")
                          ),$/;

              –




Victoria.pm                                                                 27
C Perl, C Perl Inline, C Perl XS, C Perl Guts   Abram Hindle




        Get Help
          • Where to get Help?
              – perldoc Inline

              – perldoc Inline::C

              – perldoc Inline::C-Cookbook

              – perldoc perlguts

              – perldoc perlapi

              – perldoc perlxs

              – perldoc perlxstut

              – perldoc perlembed




Victoria.pm                                              28
C Perl, C Perl Inline, C Perl XS, C Perl Guts                                             Abram Hindle



        References

        [1] I NGERSON , B. Inline::c - write perl subroutines in c.

        [2] I NGERSON , B., AND WATKISS , N. Inline - write perl subroutines in other
              programming languages.

        [3] M AC E ACHERN , D., AND O RWANT, J. perlembed - how to embed perl in your c
              program.

        [4] O KAMOTO, J. perlxstut - tutorial for writing xsubs.

        [5] P ORTERS , P. . perlguts - introduction to the perl api.

        [6] R OEHRICH , D., O KAMOTO, J., AND S TUHL , B. perlapi - autogenerated
              documentation for the perl public api.

        [7] R OEHRICH , D., AND P ORTERS , T. P. perlxs - xs language reference manual.



Victoria.pm                                                                                        29

March2004-CPerlRun

  • 1.
    C Perl, CPerl Inline, C Perl XS, C Perl Guts Abram Hindle C Perl, C Perl Inline, C Perl XS, C Perl Guts Abram Hindle Victoria Perl Mongers (victoria.pm.org) abez@abez.ca March 16, 2004 Victoria.pm 1
  • 2.
    C Perl, CPerl Inline, C Perl XS, C Perl Guts Abram Hindle This Presentation • What am I going to Cover? – Inline::C – Perl Data Structures / Guts – XS Victoria.pm 2
  • 3.
    C Perl, CPerl Inline, C Perl XS, C Perl Guts Abram Hindle This Presentation • What am I not going to Cover? – How to program in C – C++ – Anything in depth – Magic Perl Guts – OO and Perl Guts – References and Perl Guts – SWIG (maybe you should take a look if you’re wrapping a lib) Victoria.pm 3
  • 4.
    C Perl, CPerl Inline, C Perl XS, C Perl Guts Abram Hindle Inline::C • What is it? – Write Perl Subroutines in C [1] – Compile and Link C into Perl – Embed subroutines into perl scripts and modules – Automatically Wrap functions based on prototypes. Victoria.pm 4
  • 5.
    C Perl, CPerl Inline, C Perl XS, C Perl Guts Abram Hindle Inline::C • How do you use Inline::C? – use Inline C => CODE; – bind Inline C => CODE; ∗ Dynamic generation of C code. – use Inline C; __END__ __C__ void cCode() { } Victoria.pm 5
  • 6.
    C Perl, CPerl Inline, C Perl XS, C Perl Guts Abram Hindle Inline::C • How do you use Inline::C? – Inline::C parses the function prototypes and wraps them into perl. – Function prototypes should be in ANSI style ∗ return-type function-name ( type-name-pairs ) ... Victoria.pm 6
  • 7.
    C Perl, CPerl Inline, C Perl XS, C Perl Guts Abram Hindle Inline::C • Which types are supported? – void → nothing – double → scalar – char * → string – SV* → Scalar – long → Scalar – float is not supported but you can support it Victoria.pm 7
  • 8.
    C Perl, CPerl Inline, C Perl XS, C Perl Guts Abram Hindle Inline::C • Example use Inline C; helloWorld(); __END__ __C__ void helloWorld() { printf("Hello worldn"); } Victoria.pm 8
  • 9.
    C Perl, CPerl Inline, C Perl XS, C Perl Guts Abram Hindle Inline::C • Example use Inline C; hello(’World’); hello(42); hello(42,42); hello(undef); __END__ __C__ void hello(char * string) { printf("Hello %sn",string); } Victoria.pm 9
  • 10.
    C Perl, CPerl Inline, C Perl XS, C Perl Guts Abram Hindle Inline::C • Example (perl guts) use Inline C; $a = "HEY"; hello(’World’,1,42,undef,’Universe’,$a); __END__ __C__ void hello(SV* name1, ...) { Inline_Stack_Vars; int i = 0; STRLEN count; for (i = 0; i < Inline_Stack_Items; i++) { char * string = SvPV(Inline_Stack_Item(i), count); printf("Hello %sn",string); } } Victoria.pm 10
  • 11.
    C Perl, CPerl Inline, C Perl XS, C Perl Guts Abram Hindle Inline::C • Inline Stack Access macros – Inline Stack Vars - put this macros at the top of the subroutine as it defines new various for Inline Stack macros to work on – Inline Stack Items - how many items are on the stack – Inline Stack Item(i) - get the item at index i in the stack – see perldoc Inline::C Victoria.pm 11
  • 12.
    C Perl, CPerl Inline, C Perl XS, C Perl Guts Abram Hindle Perl Guts • Types in C [5] – SV - Scalar Value – AV - Array Value – HV - Hash Value – IV - Integer Value * – UV - Unsigned Value * – NV - Double Value * – PV - String Value * – * return values Victoria.pm 12
  • 13.
    C Perl, CPerl Inline, C Perl XS, C Perl Guts Abram Hindle Perl Guts • Convert Scalars [5] ( these are macros ) – int SvIV(SV*) – unsigned int SvUV(SV*) – double SvNV(SV*) – char * SvPV(SV*, STRLEN len) ∗ puts length in len, i is the buffer in SV* – char * SvPV nolen(SV*) Victoria.pm 13
  • 14.
    C Perl, CPerl Inline, C Perl XS, C Perl Guts Abram Hindle Perl Guts • Set scalars [5] ( these are macros ) – void sv setiv(SV*, IV); – void sv setuv(SV*, UV); – void sv setnv(SV*, double); – void sv setpv(SV*, const char*); – void sv setpvn(SV*, const char*, int) Victoria.pm 14
  • 15.
    C Perl, CPerl Inline, C Perl XS, C Perl Guts Abram Hindle Perl Guts • Create scalars [5] ( these are macros ) – SV* newSViv(IV); – SV* newSVuv(UV); – SV* newSVnv(double); – SV* newSVpv(const char*, int); – SV* newSVpvn(const char*, int); – SV* newSVpvf(const char*, ...); – SV* newSVsv(SV*); Victoria.pm 15
  • 16.
    C Perl, CPerl Inline, C Perl XS, C Perl Guts Abram Hindle Perl Guts • Arrays [5] – Make an array ∗ create - AV* newAV(); ∗ create - AV* av make(I32 num, SV **ptr); – Operations ∗ push - void av push(AV*, SV*); ∗ pop - SV* av pop(AV*); ∗ shift - SV* av shift(AV*); ∗ unshift - void av unshift(AV*, I32 num); Victoria.pm 16
  • 17.
    C Perl, CPerl Inline, C Perl XS, C Perl Guts Abram Hindle Perl Guts • Arrays [5] – length - I32 av len(AV*); – fetch - SV** av fetch(AV*, I32 key, I32 lval); – store - SV** av store(AV*, I32 key, SV* val); – clear - void av clear(AV*); – destroy - void av undef(AV*); – expand - void av extend(AV*, I32 key); Victoria.pm 17
  • 18.
    C Perl, CPerl Inline, C Perl XS, C Perl Guts Abram Hindle Perl Guts • Hashes – HV* newHV(); – SV** hv store(HV*, const char* key, U32 klen, SV* val, U32 hash); – SV** hv fetch(HV*, const char* key, U32 klen, I32 lval); – bool hv exists(HV*, const char* key, U32 klen); – SV* hv delete(HV*, const char* key, U32 klen, I32 flags); – void hv clear(HV*); – void hv undef(HV*); Victoria.pm 18
  • 19.
    C Perl, CPerl Inline, C Perl XS, C Perl Guts Abram Hindle Perl Guts • Hash iteration – I32 hv iterinit(HV*); – HE* hv iternext(HV*); – char* hv iterkey(HE* entry, I32* retlen); – SV* hv iterval(HV*, HE* entry); – SV* hv iternextsv(HV*, char** key, I32* retlen); Victoria.pm 19
  • 20.
    C Perl, CPerl Inline, C Perl XS, C Perl Guts Abram Hindle Perl Guts • Package Vars [5] – SV* get sv("package::varname", TRUE); – AV* get av("package::varname", TRUE); – HV* get hv("package::varname", TRUE); Victoria.pm 20
  • 21.
    C Perl, CPerl Inline, C Perl XS, C Perl Guts Abram Hindle Perl Guts • Mortality – If you have temporary values such as those that are returned or used temporarily you want the garbage collection to handle it properley. – SV* sv newmortal() – SV* sv 2mortal(SV* sv) Victoria.pm 21
  • 22.
    C Perl, CPerl Inline, C Perl XS, C Perl Guts Abram Hindle XS • What is XS? – interface description format – Integrate Perl and C code / libs – A language that is used to integrate C w/ Perl – Wraps C calls Victoria.pm 22
  • 23.
    C Perl, CPerl Inline, C Perl XS, C Perl Guts Abram Hindle XS • Into the fire: [4] - Some of this is ripped from the perlxstut – h2xs -A -n PackageName – Edit PackageName.xs – perl Makefile.PL – make – Make a test script in the PackageName directory – make install – only do this if your test script has problems finding PackageName Victoria.pm 23
  • 24.
    C Perl, CPerl Inline, C Perl XS, C Perl Guts Abram Hindle XS • The .xs file – Prototypes are done differently, see perldoc perlxs and perlxstut – First line, return type – Second line, prototype in K&R – Following lines, type the parameters (newline is the delimiter) – int strcmp(str1,str2) char *str1 char *str2 Victoria.pm 24
  • 25.
    C Perl, CPerl Inline, C Perl XS, C Perl Guts Abram Hindle XS • Lets wrap a already existing function (add this to your .xs) – strcmp – #include <string.h> int strcmp(str1,str2) char *str1 char *str2 – That’s it Victoria.pm 25
  • 26.
    C Perl, CPerl Inline, C Perl XS, C Perl Guts Abram Hindle XS • Lets write a new function (add this to your .xs) – hello – void hello() CODE: printf("Hello Worldn"); – That’s it Victoria.pm 26
  • 27.
    C Perl, CPerl Inline, C Perl XS, C Perl Guts Abram Hindle XS • Lets see our test driver (after make install) #!/usr/bin/perl use Hello; Hello::hello(); print join(" ", Hello::strcmp("a","b"), Hello::strcmp("a","a"), Hello::strcmp("bbbb","aaaa") ),$/; – Victoria.pm 27
  • 28.
    C Perl, CPerl Inline, C Perl XS, C Perl Guts Abram Hindle Get Help • Where to get Help? – perldoc Inline – perldoc Inline::C – perldoc Inline::C-Cookbook – perldoc perlguts – perldoc perlapi – perldoc perlxs – perldoc perlxstut – perldoc perlembed Victoria.pm 28
  • 29.
    C Perl, CPerl Inline, C Perl XS, C Perl Guts Abram Hindle References [1] I NGERSON , B. Inline::c - write perl subroutines in c. [2] I NGERSON , B., AND WATKISS , N. Inline - write perl subroutines in other programming languages. [3] M AC E ACHERN , D., AND O RWANT, J. perlembed - how to embed perl in your c program. [4] O KAMOTO, J. perlxstut - tutorial for writing xsubs. [5] P ORTERS , P. . perlguts - introduction to the perl api. [6] R OEHRICH , D., O KAMOTO, J., AND S TUHL , B. perlapi - autogenerated documentation for the perl public api. [7] R OEHRICH , D., AND P ORTERS , T. P. perlxs - xs language reference manual. Victoria.pm 29