Commit | Line | Data |
fe14fcc3 |
1 | This directory contains an example of how you might link in C subroutines |
2 | with perl to make your own special copy of perl. In the perl distribution |
3 | directory, there will be (after make is run) a file called uperl.o, which |
4 | is all of perl except for a single undefined subroutine, named userinit(). |
5 | See usersub.c. |
6 | |
7 | The sole purpose of the userinit() routine is to call the initialization |
8 | routines for any modules that you want to link in. In this example, we just |
55204971 |
9 | call init_curses(), which sets up to link in the System V curses routines. |
fe14fcc3 |
10 | You'll find this in the file curses.c, which is the processed output of |
55204971 |
11 | curses.mus. (To get BSD curses, replace curses.mus with bsdcurses.mus.) |
fe14fcc3 |
12 | |
13 | The magicname() routine adds variable names into the symbol table. Along |
14 | with the name of the variable as Perl knows it, we pass a structure containing |
15 | an index identifying the variable, and the names of two C functions that |
16 | know how to set or evaluate a variable given the index of the variable. |
17 | Our example uses a macro to handle this conveniently. |
18 | |
19 | The init routine calls make_usub() to add user-defined subroutine names |
20 | into the symbol table. The arguments are |
21 | |
22 | make_usub(subname, subindex, subfunc, filename); |
23 | char *subname; |
24 | int subindex; |
25 | int subfunc(); |
26 | char *filename; |
27 | |
28 | The subname is the name that will be used in the Perl program. The subindex |
29 | will be passed to subfunc() when it is called to tell it which C function |
30 | is desired. subfunc() is a glue routine that translates the arguments |
31 | from Perl internal stack form to the form required by the routine in |
32 | question, calls the desired C function, and then translates any return |
33 | value back into the stack format. The glue routine used by curses just |
34 | has a large switch statement, each branch of which does the processing |
35 | for a particular C function. The subindex could, however, be used to look |
36 | up a function in a dynamically linked library. No example of this is |
37 | provided. |
38 | |
39 | As a help in producing the glue routine, a preprocessor called "mus" lets |
40 | you specify argument and return value types in a tabular format. An entry |
41 | such as: |
42 | |
43 | CASE int waddstr |
44 | I WINDOW* win |
45 | I char* str |
46 | END |
47 | |
48 | indicates that waddstr takes two input arguments, the first of which is a |
49 | pointer to a window, and the second of which is an ordinary C string. It |
50 | also indicates that an integer is returned. The mus program turns this into: |
51 | |
52 | case US_waddstr: |
53 | if (items != 2) |
54 | fatal("Usage: &waddstr($win, $str)"); |
55 | else { |
56 | int retval; |
57 | WINDOW* win = *(WINDOW**) str_get(st[1]); |
58 | char* str = (char*) str_get(st[2]); |
59 | |
60 | retval = waddstr(win, str); |
61 | str_numset(st[0], (double) retval); |
62 | } |
63 | return sp; |
64 | |
65 | It's also possible to have output parameters, indicated by O, and input/ouput |
66 | parameters indicated by IO. |
67 | |
68 | The mus program isn't perfect. You'll note that curses.mus has some |
69 | cases which are hand coded. They'll be passed straight through unmodified. |
70 | You can produce similar cases by analogy to what's in curses.c, as well |
71 | as similar routines in the doarg.c, dolist.c and doio.c routines of Perl. |
72 | The mus program is only intended to get you about 90% there. It's not clear, |
73 | for instance, how a given structure should be passed to Perl. But that |
74 | shouldn't bother you--if you've gotten this far, it's already obvious |
75 | that you are totally mad. |
76 | |
77 | Here's an example of how to return an array value: |
78 | |
79 | case US_appl_errlist: |
80 | if (!wantarray) { |
81 | str_numset(st[0], (double) appl_nerr); |
82 | return sp; |
83 | } |
84 | astore(stack, sp + appl_nerr, Nullstr); /* extend stack */ |
85 | st = stack->ary_array + sp; /* possibly realloced */ |
86 | for (i = 0; i < appl_nerr; i++) { |
87 | tmps = appl_errlist[i]; |
88 | st[i] = str_2mortal(str_make(tmps,strlen(tmps))); |
89 | } |
90 | return sp + appl_nerr - 1; |
91 | |
92 | |
93 | In addition, there is a program, man2mus, that will scan a man page for |
94 | function prototypes and attempt to construct a mus CASE entry for you. It has |
95 | to guess about input/output parameters, so you'll have to tidy up after it. |
96 | But it can save you a lot of time if the man pages for a library are |
97 | reasonably well formed. |
98 | |
55204971 |
99 | If you happen to have curses on your machine, you might try compiling |
fe14fcc3 |
100 | a copy of curseperl. The "pager" program in this directory is a rudimentary |
101 | start on writing a pager--don't believe the help message, which is stolen |
102 | from the less program. |
103 | |
fe14fcc3 |
104 | User-defined subroutines may not currently be called as a signal handler, |
105 | though a signal handler may itself call a user-defined subroutine. |
55204971 |
106 | |
107 | There are now glue routines to call back from C into Perl. In usersub.c |
108 | in this directory, you'll find callback() and callv(). The callback() |
109 | routine presumes that any arguments to pass to the Perl subroutine |
110 | have already been pushed onto the Perl stack. The callv() routine |
111 | is a wrapper that pushes an argv-style array of strings onto the |
112 | stack for you, and then calls callback(). Be sure to recheck your |
113 | stack pointer after returning from these routine, since the Perl code |
114 | may have reallocated it. |