📄 readme
字号:
This directory contains an example of how you might link in C subroutineswith perl to make your own special copy of perl. In the perl distributiondirectory, there will be (after make is run) a file called uperl.o, whichis all of perl except for a single undefined subroutine, named userinit().See usersub.c.The sole purpose of the userinit() routine is to call the initializationroutines for any modules that you want to link in. In this example, we justcall init_curses(), which sets up to link in the System V curses routines.You'll find this in the file curses.c, which is the processed output ofcurses.mus. (To get BSD curses, replace curses.mus with bsdcurses.mus.)The magicname() routine adds variable names into the symbol table. Alongwith the name of the variable as Perl knows it, we pass a structure containingan index identifying the variable, and the names of two C functions thatknow how to set or evaluate a variable given the index of the variable.Our example uses a macro to handle this conveniently.The init routine calls make_usub() to add user-defined subroutine namesinto the symbol table. The arguments are make_usub(subname, subindex, subfunc, filename); char *subname; int subindex; int subfunc(); char *filename;The subname is the name that will be used in the Perl program. The subindexwill be passed to subfunc() when it is called to tell it which C functionis desired. subfunc() is a glue routine that translates the argumentsfrom Perl internal stack form to the form required by the routine inquestion, calls the desired C function, and then translates any returnvalue back into the stack format. The glue routine used by curses justhas a large switch statement, each branch of which does the processingfor a particular C function. The subindex could, however, be used to lookup a function in a dynamically linked library. No example of this isprovided.As a help in producing the glue routine, a preprocessor called "mus" letsyou specify argument and return value types in a tabular format. An entrysuch as: CASE int waddstr I WINDOW* win I char* str ENDindicates that waddstr takes two input arguments, the first of which is apointer to a window, and the second of which is an ordinary C string. Italso indicates that an integer is returned. The mus program turns this into: case US_waddstr: if (items != 2) fatal("Usage: &waddstr($win, $str)"); else { int retval; WINDOW* win = *(WINDOW**) str_get(st[1]); char* str = (char*) str_get(st[2]); retval = waddstr(win, str); str_numset(st[0], (double) retval); } return sp;It's also possible to have output parameters, indicated by O, and input/ouputparameters indicated by IO.The mus program isn't perfect. You'll note that curses.mus has somecases which are hand coded. They'll be passed straight through unmodified.You can produce similar cases by analogy to what's in curses.c, as wellas similar routines in the doarg.c, dolist.c and doio.c routines of Perl.The mus program is only intended to get you about 90% there. It's not clear,for instance, how a given structure should be passed to Perl. But thatshouldn't bother you--if you've gotten this far, it's already obviousthat you are totally mad.Here's an example of how to return an array value: case US_appl_errlist: if (!wantarray) { str_numset(st[0], (double) appl_nerr); return sp; } astore(stack, sp + appl_nerr, Nullstr); /* extend stack */ st = stack->ary_array + sp; /* possibly realloced */ for (i = 0; i < appl_nerr; i++) { tmps = appl_errlist[i]; st[i] = str_2mortal(str_make(tmps,strlen(tmps))); } return sp + appl_nerr - 1;In addition, there is a program, man2mus, that will scan a man page forfunction prototypes and attempt to construct a mus CASE entry for you. It hasto guess about input/output parameters, so you'll have to tidy up after it.But it can save you a lot of time if the man pages for a library arereasonably well formed.If you happen to have curses on your machine, you might try compilinga copy of curseperl. The "pager" program in this directory is a rudimentarystart on writing a pager--don't believe the help message, which is stolenfrom the less program.User-defined subroutines may not currently be called as a signal handler,though a signal handler may itself call a user-defined subroutine.There are now glue routines to call back from C into Perl. In usersub.cin this directory, you'll find callback() and callv(). The callback()routine presumes that any arguments to pass to the Perl subroutinehave already been pushed onto the Perl stack. The callv() routineis a wrapper that pushes an argv-style array of strings onto thestack for you, and then calls callback(). Be sure to recheck yourstack pointer after returning from these routine, since the Perl codemay have reallocated it.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -