usersub: HOW TO 
Author Message
 usersub: HOW TO

#--------------------------------CUT HERE-------------------------------------
#! /bin/sh
#
# This is a shell archive.  Save this into a file, edit it
# and delete all lines above this comment.  Then give this
# file to sh by executing the command "sh file".  The files
# will be extracted into the current directory owned by
# you with default permissions.
#
# The files contained herein are:
#
# -r--r--r--  1 robt         7077 Aug 29 15:58 usub.doc
# -r--r--r--  1 robt         1686 Aug 29 15:49 ex1.mus
# -r--r--r--  1 robt         1714 Aug 29 15:49 ex2.mus
# -r--r--r--  1 robt         2287 Aug 29 15:49 ex3.mus
# -r--r--r--  1 robt          480 Aug 29 15:56 exfns.c
# -r--r--r--  1 robt          266 Aug 29 15:36 exfns.h
# -r--r--r--  1 robt          892 Aug 29 23:20 makefile
# -r--r--r--  1 robt         1370 Aug 29 16:09 extest.pl
#
echo 'x - usub.doc'
if test -f usub.doc; then echo 'shar: not overwriting usub.doc'; else
sed 's/^X//' << '________This_Is_The_END________' > usub.doc
X/*
X *   Last edited by:  $Author: robt $
X *               on:  $Date: 1992/08/29 19:58:19 $
X *         Filename:  $RCSfile: usub.doc,v $
X *         Revision:  $Revision: 1.3 $
X */
X
X                 usub: Hooking C functions in to perl
X                 ------------------------------------
X

X
XThese notes do not represent the views of Morgan Stanley & Co. in any
Xway.  I am solely responsible for the contents.
X
XThese notes describe in detail how to hook functions into perl using
Xthe "usersub" mechanism.  Assuming people are interested, I will post
Xnew versions when (and if!) I figure out more, particularly about
Xassociative arrays.  You might want to skip reading this all together
Xand just look at the sample programs (see the makefile).
X
XIntroduction
X------------
X
XYou should have the following files:
X
X    makefile            Makes the examples
X    usub.doc            These notes
X    ex1.mus             Glue to hook "opie" from exfns.c into perl
X    ex2.mus             Glue to hook more of exfns.c into perl
X    ex3.mus             Same as ex3.mus, with an example of
X                        returning an array.
X    exfns.c             Functions to be hooked in to perl in examples
X    exfns.h             Header file for exfns.c
X    extest.pl           Small program to test that the new functions
X                        are there.
X    
XYou will also need uperl.o (should have been created when perl was
Xbuilt), the .h files from perl, and the program mus, all of which
Xshould be in your perl source directory.  You should also take a look
Xat README in the usub directory under the perl source.  
X
XDANGER WILL ROBINSON!
X---------------------
X
XIf you are using perl with patchlevel < 20, you may have memory
Xleakage problems.  I did, with functions that return arrays.  This is
Xapparently due to a problem which has been fixed.  When I compile
Xusing patchlevel 35, I have no such problems.  This may not be a big
Xdeal - I had to run around 100K calls before perl barfed.
X
XBasic Structure
X---------------
X
Xperl hooks in functions and variables using two enumerated variables,
Xand four functions.
X
X    1) An enum variable called usersubs, the elements of which look like
X       US_functionName.  For example:
X
X            static enum usersubs { US_aGreatFunction };
X
X       These values will be passed to usersub (see below) so it can
X       tell what function has been called.
X
X    2) An enum variable called uservars, the elements of which look like
X       UV_variableName.  For example:
X
X            static enum uservars { UV_anImportantVariable };
X
X       These values will be passed to userset and userval (see below) so
X       tell what variable is being set/retrieved.
X    
X    3) Four functions, userinit, usersub, userset, and userval, the
X       latter two two of which are required only if one is using uservars.
X        
Xuserinit performs any initializations needed.  This can be
X
X    1) Any initialization needed by the code you're hooking in.  
X    2) Registering the functions enumerated in usersubs using make_usub.
X    3) Setting the uf_set and uf_get fields of a global struct ufuncs
X       for use by MAGICVAR.
X    4) Registering the variables enumerated in uservals using the
X       MAGICVAR macro.
X
Xusersub gets passed the enumerated value of the function being called
X(eg US_myFunction), the number of parameters, and a pointer to the perl
Xstack.  It is just a switch on the US_ value, each case of which must
Xpull parameters off the stack and put them back on appropriately.  The
Xmus program helps in this - if a function is simple enough, it will fill
Xin the code for you.  Our examples use mus to do this.
X
Xuserval is called when the perl program tries to get the value of a
Xvariable defined in your struct uservals.  It gets passed a (STR *)
Xwhich it must fill in, usually using the functions str_numset or
Xstr_set.
X
Xuserset is called when the perl program tries to set the value of a
Xvariable defined in your struct uservals.  It gets passed a (STR *)
Xfrom which it must extract and set the variable, usually using
Xstr_gnum or str_get.  (These could be either functions or macros,
Xdepending on the value of the symbol CRIPPLED_CC - don't worry about
Xit.).
X
Xmus
X---
X
Xmus is a program which makes using usub easier.  The input to mus is
Xan "extended" C source.  The output of mus is a C program which
Xcontains code to check the number of arguments, extract the arguments
Xfrom the perl stack, calls your function and then puts the result back
Xon the stack.  It only handles scalar values, but see example 3 for
Xthe way to return an array.  You should run mus on the examples and
Xlook at the resulting C programs.  In particular, doing this will show
Xyou how to use str_set, str_setnum, str_get, and str_gnum.
X
XA Handy Hint
X------------
X
XIf you compile with debugging on, you can dbx (or whatever) your copy
Xof perl and stop in usersub to see what's going on like this:
X
X       $ dbx myperl
X       (dbx) stop in usersub
X       (dbx) run -de 0
X       <DB>1 $x = &myFunction('hello');  # now you're in the perl de{*filter*}
X       stopped at usersub at line ....   # now you're in dbx
X       (dbx)
X            
X            
XIf you trace in far enough, st[1] will be the first argument you passed
Xto the function.  Have fun...
X
XExample 1
X---------
X
XIn this example, we have a function already written, with prototype
X
X    double opie(double);
X
Xin the file exfns.c, and we want to call it from perl like this
X
X    $x = 12.3;
X    print &opie($x), "\n";
X
XThe file ex1.mus contains all that is needed.  In this simple
Xcase, that's not much.  The makefile runs ex1.mus through the mus
Xpreprocessor, creating ex1.c.  Since all we want opie to do is
Xreturn a scalar, we don't have to worry about the perl stack and the
XCASE/END construction does the trick.
X
XExample 2
X---------
X
XIn this example, we add two functions from exfns.c
X
X    int    andy(int);
X    char * helen(int, char *);
X
Xand our own "magic" variable
X    
X    int Mayberry;
X
XThey will be used in perl like this
X
X    $n = &andy(0);
X    $x = &helen($n, "crump"); # This could change the value of $Mayberry
X    print $Mayberry, "\n";
X    $Mayberry = 12;
X
XAgain, we can use mus directly for this, and the code is in
Xex2.mus.  The main difference, other than using different function
Xtypes is that we have two additional functions, userset and userval,
Xwhich are used when we set or retrieve the value of a user variable,
Xin this case $Mayberry.  Note the way in which these functions are
Xregistered in userinit.
X    
XExample 3 (Harder Stuff - returning arrays)
X-------------------------------------------
X
Xex3.mus is the same as ex2.mus, except that a new function,
Xcalled otis has been added.  &otis($n) returns an array of the squares
Xof the integers between 1 and $n.  This involves some messing around
Xwith the perl stack, and using the function astore to enlarge the
Xstack, the function str_nmake to create new numeric elements, and the
Xfunction str_2mortal to let perl know that it can reclaim the memory
Xused for the return value.
X
X
X
X
________This_Is_The_END________
if test `wc -c < usub.doc` -ne     7077; then
        echo 'shar: usub.doc was damaged during transit (should have been     7077 bytes)'
fi
fi              ; : end of overwriting check
echo 'x - ex1.mus'
if test -f ex1.mus; then echo 'shar: not overwriting ex1.mus'; else
sed 's/^X//' << '________This_Is_The_END________' > ex1.mus
X/*
X *   Last edited by:  $Author: robt $
X *               on:  $Date: 1992/08/29 19:49:20 $
X *         Filename:  $RCSfile: ex1.mus,v $
X *         Revision:  $Revision: 1.2 $
X */
X
X#include "EXTERN.h"
X#include "perl.h"
X#include "exfns.h"
X
X/*
X * Try dbxing your customized perl and stop in usersub to
X * see what's going on. Do this:
X *
X *          dbx myperl
X *          (dbx) stop in usersub
X *          (dbx) run -de 0
X *
X *          <DB>1 $x = &myFunction('hello');  # now you're in perl
X *
X * and you'll find yourself in usersub.
X */
X
X
X/*
X * We'll be hooking in only one function, opie from exfns.c,
X * and no variables.
X */
X
Xstatic enum usersubs {
X    US_opie
X};
X
Xstatic int usersub();
Xint userinit();
X
Xint
Xuserinit()
X{
X    char * filename = "ex1.mus";
X    
X    /* Register opie with perl */
X    make_usub("opie", US_opie,       usersub, filename);
X}
X
X
X
Xstatic int
Xusersub(ix, sp, items)
X    int ix;               /* the US_ value of the function being called */
X    register int sp;      /* perl stack pointer                         */
X    register int items;   /* # of args passed                           */
X{
X    STR **st = stack->ary_array + sp; /* used in code generated by mus */
X    register STR *Str;         /* used in str_get and str_gnum macros */
X
X    switch (ix) {
X
X/*
X * Running mus ex1.mus > ex1.c will cause this to be ...

read more »



Thu, 16 Feb 1995 12:27:37 GMT  
 usersub: HOW TO

        [ usub examples deleted ]

I have some suggestions for the makefile.

Some makes can't make a .o from a .mus even if they know how to make
a .c from a .mus. I suggest you change

        .mus.c:
                mus $*.mus > $*.c

to
        .mus.o:
                mus $*.mus > $*.c
                $(CC) -c $(CFLAGS) $*.c

if you have such a make (GNU make isn't one of them).

Also the libs perl wants are missing. You can find them like this:

LIBS = `/bin/sh -c '. $(PERLSRC)/config.sh ; echo $$libs'`

        Jan D.



Fri, 17 Feb 1995 15:20:37 GMT  
 usersub: HOW TO

   I have some suggestions for the makefile.

   [good suggestions deleted]

Is mus supposed to be in some normal place?  Ours is in
our perl distribution tree.

I added these lines:

MUS=$(PERLSRC)/mus

.mus.o:
        $(MUS) $*.mus > $*.c
        $(CC) -c $(CFLAGS) $*.c

BTW, except for tinkering with the makefile, the examples
worked like a charm.  Kudos to Rob Torop!

Jon Vander Hill



Sat, 18 Feb 1995 03:03:56 GMT  
 
 [ 3 post ] 

 Relevant Pages 

1. Need help with setuid scripts which use usersub.o

2. How to get $; from usersub

3. usersub functions in a different package.

4. sort usersub.

5. calling do_eval from usersub

6. usersub

7. troubles with usersub

8. usersub advice requested

9. usersub problems when invoked within a subroutine

10. usersub: How To

11. HELP: with usersub callback

12. How to pass a function in a usersub?

 

 
Powered by phpBB® Forum Software