Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | .\" Automatically generated by Pod::Man v1.34, Pod::Parser v1.13 |
2 | .\" | |
3 | .\" Standard preamble: | |
4 | .\" ======================================================================== | |
5 | .de Sh \" Subsection heading | |
6 | .br | |
7 | .if t .Sp | |
8 | .ne 5 | |
9 | .PP | |
10 | \fB\\$1\fR | |
11 | .PP | |
12 | .. | |
13 | .de Sp \" Vertical space (when we can't use .PP) | |
14 | .if t .sp .5v | |
15 | .if n .sp | |
16 | .. | |
17 | .de Vb \" Begin verbatim text | |
18 | .ft CW | |
19 | .nf | |
20 | .ne \\$1 | |
21 | .. | |
22 | .de Ve \" End verbatim text | |
23 | .ft R | |
24 | .fi | |
25 | .. | |
26 | .\" Set up some character translations and predefined strings. \*(-- will | |
27 | .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left | |
28 | .\" double quote, and \*(R" will give a right double quote. | will give a | |
29 | .\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to | |
30 | .\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C' | |
31 | .\" expand to `' in nroff, nothing in troff, for use with C<>. | |
32 | .tr \(*W-|\(bv\*(Tr | |
33 | .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' | |
34 | .ie n \{\ | |
35 | . ds -- \(*W- | |
36 | . ds PI pi | |
37 | . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch | |
38 | . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch | |
39 | . ds L" "" | |
40 | . ds R" "" | |
41 | . ds C` "" | |
42 | . ds C' "" | |
43 | 'br\} | |
44 | .el\{\ | |
45 | . ds -- \|\(em\| | |
46 | . ds PI \(*p | |
47 | . ds L" `` | |
48 | . ds R" '' | |
49 | 'br\} | |
50 | .\" | |
51 | .\" If the F register is turned on, we'll generate index entries on stderr for | |
52 | .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index | |
53 | .\" entries marked with X<> in POD. Of course, you'll have to process the | |
54 | .\" output yourself in some meaningful fashion. | |
55 | .if \nF \{\ | |
56 | . de IX | |
57 | . tm Index:\\$1\t\\n%\t"\\$2" | |
58 | .. | |
59 | . nr % 0 | |
60 | . rr F | |
61 | .\} | |
62 | .\" | |
63 | .\" For nroff, turn off justification. Always turn off hyphenation; it makes | |
64 | .\" way too many mistakes in technical documents. | |
65 | .hy 0 | |
66 | .if n .na | |
67 | .\" | |
68 | .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). | |
69 | .\" Fear. Run. Save yourself. No user-serviceable parts. | |
70 | . \" fudge factors for nroff and troff | |
71 | .if n \{\ | |
72 | . ds #H 0 | |
73 | . ds #V .8m | |
74 | . ds #F .3m | |
75 | . ds #[ \f1 | |
76 | . ds #] \fP | |
77 | .\} | |
78 | .if t \{\ | |
79 | . ds #H ((1u-(\\\\n(.fu%2u))*.13m) | |
80 | . ds #V .6m | |
81 | . ds #F 0 | |
82 | . ds #[ \& | |
83 | . ds #] \& | |
84 | .\} | |
85 | . \" simple accents for nroff and troff | |
86 | .if n \{\ | |
87 | . ds ' \& | |
88 | . ds ` \& | |
89 | . ds ^ \& | |
90 | . ds , \& | |
91 | . ds ~ ~ | |
92 | . ds / | |
93 | .\} | |
94 | .if t \{\ | |
95 | . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" | |
96 | . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' | |
97 | . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' | |
98 | . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' | |
99 | . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' | |
100 | . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' | |
101 | .\} | |
102 | . \" troff and (daisy-wheel) nroff accents | |
103 | .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' | |
104 | .ds 8 \h'\*(#H'\(*b\h'-\*(#H' | |
105 | .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] | |
106 | .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' | |
107 | .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' | |
108 | .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] | |
109 | .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] | |
110 | .ds ae a\h'-(\w'a'u*4/10)'e | |
111 | .ds Ae A\h'-(\w'A'u*4/10)'E | |
112 | . \" corrections for vroff | |
113 | .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' | |
114 | .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' | |
115 | . \" for low resolution devices (crt and lpr) | |
116 | .if \n(.H>23 .if \n(.V>19 \ | |
117 | \{\ | |
118 | . ds : e | |
119 | . ds 8 ss | |
120 | . ds o a | |
121 | . ds d- d\h'-1'\(ga | |
122 | . ds D- D\h'-1'\(hy | |
123 | . ds th \o'bp' | |
124 | . ds Th \o'LP' | |
125 | . ds ae ae | |
126 | . ds Ae AE | |
127 | .\} | |
128 | .rm #[ #] #H #V #F C | |
129 | .\" ======================================================================== | |
130 | .\" | |
131 | .IX Title "C-Cookbook 3" | |
132 | .TH C-Cookbook 3 "2002-11-04" "perl v5.8.0" "User Contributed Perl Documentation" | |
133 | .SH "NAME" | |
134 | C Cookbook \- A Cornucopia of Inline C Recipes | |
135 | .SH "DESCRIPTION" | |
136 | .IX Header "DESCRIPTION" | |
137 | It's a lot easier for most of us to cook a meal from a recipe, rather | |
138 | than just throwing things into a pot until something edible forms. So it | |
139 | is with programming as well. \f(CW\*(C`Inline.pm\*(C'\fR makes C programming for Perl | |
140 | as easy as possible. Having a set of easy to understand samples, makes | |
141 | it simpler yet. | |
142 | .PP | |
143 | This Cookbook is intended to be an evergrowing repository of small yet | |
144 | complete coding examples; each showing how to accomplish a particular | |
145 | task with Inline. Each example is followed by a short discussion, | |
146 | explaining in detail the particular features that are being | |
147 | demonstrated. | |
148 | .PP | |
149 | Many of these recipes are apdapted from email discussions I have had | |
150 | with Inline users around the world. It has been my experience so far, | |
151 | that Inline provides an elegant solution to almost all problems | |
152 | involving Perl and C. | |
153 | .PP | |
154 | Bon Appetit! | |
155 | .SH "Appetizers" | |
156 | .IX Header "Appetizers" | |
157 | .Sh "Hello, world" | |
158 | .IX Subsection "Hello, world" | |
159 | .IP "Problem" 4 | |
160 | .IX Item "Problem" | |
161 | It seems that the first thing any programmer wants to do when he learns | |
162 | a new programming technique is to use it to greet the Earth. How can I | |
163 | do this using Inline? | |
164 | .IP "Solution" 4 | |
165 | .IX Item "Solution" | |
166 | .Vb 1 | |
167 | \& use Inline C => <<'END_C'; | |
168 | .Ve | |
169 | .Sp | |
170 | .Vb 4 | |
171 | \& void greet() { | |
172 | \& printf("Hello, world\en"); | |
173 | \& } | |
174 | \& END_C | |
175 | .Ve | |
176 | .Sp | |
177 | .Vb 1 | |
178 | \& greet; | |
179 | .Ve | |
180 | .IP "Discussion" 4 | |
181 | .IX Item "Discussion" | |
182 | Nothing too fancy here. We define a single C function \f(CW\*(C`greet()\*(C'\fR which | |
183 | prints a message to \s-1STDOUT\s0. One thing to note is that since the Inline | |
184 | code comes before the function call to \f(CW\*(C`greet\*(C'\fR, we can call it as a | |
185 | bareword (no parentheses). | |
186 | .IP "See Also" 4 | |
187 | .IX Item "See Also" | |
188 | See Inline and Inline::C for basic info about \f(CW\*(C`Inline.pm\*(C'\fR. | |
189 | .IP "Credits" 4 | |
190 | .IX Item "Credits" | |
191 | Brian Kernigan | |
192 | .Sp | |
193 | Dennis Ritchie | |
194 | .Sh "One Liner" | |
195 | .IX Subsection "One Liner" | |
196 | .IP "Problem" 4 | |
197 | .IX Item "Problem" | |
198 | A concept is valid in Perl only if it can be shown to work in one line. | |
199 | Can Inline reduce the complexities of Perl/C interaction to a one\-liner? | |
200 | .IP "Solution" 4 | |
201 | .IX Item "Solution" | |
202 | .Vb 1 | |
203 | \& perl -e 'use Inline C=>q{void greet(){printf("Hello, world\en");}};greet' | |
204 | .Ve | |
205 | .IP "Discussion" 4 | |
206 | .IX Item "Discussion" | |
207 | Try doing that in \s-1XS\s0 :\-) | |
208 | .IP "See Also" 4 | |
209 | .IX Item "See Also" | |
210 | My email signature of late is: | |
211 | .Sp | |
212 | .Vb 1 | |
213 | \& perl -le 'use Inline C=>q{SV*JAxH(char*x){return newSVpvf("Just Another %s Hacker",x);}};print JAxH+Perl' | |
214 | .Ve | |
215 | .Sp | |
216 | A bit fancier but a few bytes too long to qualify as a true one liner :\-( | |
217 | .IP "Credits" 4 | |
218 | .IX Item "Credits" | |
219 | \&\*(L"Eli the Bearded\*(R" <elijah@workspot.net> gave me the idea that I should | |
220 | have an Inline one-liner as a signature. | |
221 | .SH "Meat & Potatoes" | |
222 | .IX Header "Meat & Potatoes" | |
223 | .Sh "Data Types" | |
224 | .IX Subsection "Data Types" | |
225 | .IP "Problem" 4 | |
226 | .IX Item "Problem" | |
227 | How do I pass different types of data to and from Inline C functions; | |
228 | like strings, numbers and integers? | |
229 | .IP "Solution" 4 | |
230 | .IX Item "Solution" | |
231 | .Vb 2 | |
232 | \& # vowels.pl | |
233 | \& use Inline C; | |
234 | .Ve | |
235 | .Sp | |
236 | .Vb 2 | |
237 | \& $filename = $ARGV[0]; | |
238 | \& die "Usage: perl vowels.pl filename\en" unless -f $filename; | |
239 | .Ve | |
240 | .Sp | |
241 | .Vb 4 | |
242 | \& $text = join '', <>; # slurp input file | |
243 | \& $vp = vowel_scan($text); # call our function | |
244 | \& $vp = sprintf("%03.1f", $vp * 100); # format for printing | |
245 | \& print "The letters in $filename are $vp% vowels.\en"; | |
246 | .Ve | |
247 | .Sp | |
248 | .Vb 2 | |
249 | \& __END__ | |
250 | \& __C__ | |
251 | .Ve | |
252 | .Sp | |
253 | .Vb 14 | |
254 | \& /* Find percentage of vowels to letters */ | |
255 | \& double vowel_scan(char* str) { | |
256 | \& int letters = 0; | |
257 | \& int vowels = 0; | |
258 | \& int i = 0; | |
259 | \& char c; | |
260 | \& char normalize = 'a' ^ 'A'; | |
261 | \& /* normalize forces lower case in ASCII; upper in EBCDIC */ | |
262 | \& char A = normalize | 'a'; | |
263 | \& char E = normalize | 'e'; | |
264 | \& char I = normalize | 'i'; | |
265 | \& char O = normalize | 'o'; | |
266 | \& char U = normalize | 'u'; | |
267 | \& char Z = normalize | 'z'; | |
268 | .Ve | |
269 | .Sp | |
270 | .Vb 8 | |
271 | \& while(c = str[i++]) { | |
272 | \& c |= normalize; | |
273 | \& if (c >= A && c <= Z) { | |
274 | \& letters++; | |
275 | \& if (c == A || c == E || c == I || c == O || c == U) | |
276 | \& vowels++; | |
277 | \& } | |
278 | \& } | |
279 | .Ve | |
280 | .Sp | |
281 | .Vb 2 | |
282 | \& return letters ? ((double) vowels / letters) : 0.0; | |
283 | \& } | |
284 | .Ve | |
285 | .IP "Discussion" 4 | |
286 | .IX Item "Discussion" | |
287 | This script takes a file name from the command line and prints the ratio | |
288 | of vowels to letters in that file. \f(CW\*(C`vowels.pl\*(C'\fR uses an Inline C | |
289 | function called \f(CW\*(C`vowel_scan\*(C'\fR, that takes a string argument, and returns | |
290 | the percentage of vowels as a floating point number between 0 and 1. It | |
291 | handles upper and lower case letters, and works with \s-1ASCII\s0 and \s-1EBCDIC\s0. | |
292 | It is also quite fast. | |
293 | .Sp | |
294 | Running this script produces: | |
295 | .Sp | |
296 | .Vb 2 | |
297 | \& > perl vowels.pl /usr/dict/words | |
298 | \& The letters in /usr/dict/words are 37.5% vowels. | |
299 | .Ve | |
300 | .IP "See Also" 4 | |
301 | .IX Item "See Also" | |
302 | The Perl Journal vol #19 has an article about Inline which uses this example. | |
303 | .IP "Credits" 4 | |
304 | .IX Item "Credits" | |
305 | This example was reprinted by permission of The Perl Journal. It was | |
306 | edited to work with Inline v0.30 and higher. | |
307 | .Sh "Variable Argument Lists" | |
308 | .IX Subsection "Variable Argument Lists" | |
309 | .IP "Problem" 4 | |
310 | .IX Item "Problem" | |
311 | How do I pass a variable-sized list of arguments to an Inline C function? | |
312 | .IP "Solution" 4 | |
313 | .IX Item "Solution" | |
314 | .Vb 1 | |
315 | \& greet(qw(Sarathy Jan Sparky Murray Mike)); | |
316 | .Ve | |
317 | .Sp | |
318 | .Vb 1 | |
319 | \& use Inline C => <<'END_OF_C_CODE'; | |
320 | .Ve | |
321 | .Sp | |
322 | .Vb 3 | |
323 | \& void greet(SV* name1, ...) { | |
324 | \& Inline_Stack_Vars; | |
325 | \& int i; | |
326 | .Ve | |
327 | .Sp | |
328 | .Vb 2 | |
329 | \& for (i = 0; i < Inline_Stack_Items; i++) | |
330 | \& printf("Hello %s!\en", SvPV(Inline_Stack_Item(i), PL_na)); | |
331 | .Ve | |
332 | .Sp | |
333 | .Vb 2 | |
334 | \& Inline_Stack_Void; | |
335 | \& } | |
336 | .Ve | |
337 | .Sp | |
338 | .Vb 1 | |
339 | \& END_OF_C_CODE | |
340 | .Ve | |
341 | .IP "Discussion" 4 | |
342 | .IX Item "Discussion" | |
343 | This little program greets a group of people, such as my | |
344 | coworkers. We use the \f(CW\*(C`C\*(C'\fR ellipsis syntax: "\f(CW\*(C`...\*(C'\fR", since the | |
345 | list can be of any size. | |
346 | .Sp | |
347 | Since there are no types or names associated with each argument, we | |
348 | can't expect \s-1XS\s0 to handle the conversions for us. We'll need to pop them | |
349 | off the \fBStack\fR ourselves. Luckily there are two functions (macros) | |
350 | that make this a very easy task. | |
351 | .Sp | |
352 | First, we need to begin our function with a "\f(CW\*(C`Inline_Stack_Vars\*(C'\fR" | |
353 | statement. This defines a few internal variables that we need to access | |
354 | the \fBStack\fR. Now we can use "\f(CW\*(C`Inline_Stack_Items\*(C'\fR", which returns an | |
355 | integer containing the number of arguments passed to us from Perl. | |
356 | .Sp | |
357 | \&\fB\s-1NOTE:\s0\fR It is important to \fIonly\fR use "\f(CW\*(C`Inline_Stack_\*(C'\fR" macros when | |
358 | there is an ellipsis (\f(CW\*(C`...\*(C'\fR) in the argument list, \fIor\fR the function | |
359 | has a return type of void. | |
360 | .Sp | |
361 | Second, we use the \f(CWInline_Stack_Item(x)\fR function to access each | |
362 | argument where \*(L"0 <= x < items\*(R". | |
363 | .Sp | |
364 | \&\fB\s-1NOTE:\s0\fR When using a variable length argument list, you have to | |
365 | specify at least one argument before the ellipsis. (On my compiler, | |
366 | anyway.) When \s-1XS\s0 does it's argument checking, it will complain if you | |
367 | pass in less than the number of \fIdefined\fR arguments. Therefore, there | |
368 | is currently no way to pass an empty list when a variable length list | |
369 | is expected. | |
370 | .IP "See Also" 4 | |
371 | .IX Item "See Also" | |
372 | .PD 0 | |
373 | .IP "Credits" 4 | |
374 | .IX Item "Credits" | |
375 | .PD | |
376 | .Sh "Multiple Return Values" | |
377 | .IX Subsection "Multiple Return Values" | |
378 | .IP "Problem" 4 | |
379 | .IX Item "Problem" | |
380 | How do I return a list of values from a C function? | |
381 | .IP "Solution" 4 | |
382 | .IX Item "Solution" | |
383 | .Vb 1 | |
384 | \& print map {"$_\en"} get_localtime(time); | |
385 | .Ve | |
386 | .Sp | |
387 | .Vb 1 | |
388 | \& use Inline C => <<'END_OF_C_CODE'; | |
389 | .Ve | |
390 | .Sp | |
391 | .Vb 1 | |
392 | \& #include <time.h> | |
393 | .Ve | |
394 | .Sp | |
395 | .Vb 3 | |
396 | \& void get_localtime(int utc) { | |
397 | \& struct tm *ltime = localtime(&utc); | |
398 | \& Inline_Stack_Vars; | |
399 | .Ve | |
400 | .Sp | |
401 | .Vb 11 | |
402 | \& Inline_Stack_Reset; | |
403 | \& Inline_Stack_Push(sv_2mortal(newSViv(ltime->tm_year))); | |
404 | \& Inline_Stack_Push(sv_2mortal(newSViv(ltime->tm_mon))); | |
405 | \& Inline_Stack_Push(sv_2mortal(newSViv(ltime->tm_mday))); | |
406 | \& Inline_Stack_Push(sv_2mortal(newSViv(ltime->tm_hour))); | |
407 | \& Inline_Stack_Push(sv_2mortal(newSViv(ltime->tm_min))); | |
408 | \& Inline_Stack_Push(sv_2mortal(newSViv(ltime->tm_sec))); | |
409 | \& Inline_Stack_Push(sv_2mortal(newSViv(ltime->tm_isdst))); | |
410 | \& Inline_Stack_Done; | |
411 | \& } | |
412 | \& END_OF_C_CODE | |
413 | .Ve | |
414 | .IP "Discussion" 4 | |
415 | .IX Item "Discussion" | |
416 | Perl is a language where it is common to return a list of values | |
417 | from a subroutine call instead of just a single value. C is not such | |
418 | a language. In order to accomplish this in C we need to manipulate | |
419 | the Perl call stack by hand. Luckily, Inline provides macros to make | |
420 | this easy. | |
421 | .Sp | |
422 | This example calls the system \f(CW\*(C`localtime\*(C'\fR, and returns each of the | |
423 | parts of the time struct; much like the perl builtin \f(CW\*(C`localtime()\*(C'\fR. On | |
424 | each stack push, we are creating a new Perl integer (\s-1SVIV\s0) and | |
425 | mortalizing it. The \fIsv_2mortal()\fR call makes sure that the reference | |
426 | count is set properly. Without it, the program would leak memory. | |
427 | .Sp | |
428 | \&\s-1NOTE:\s0 | |
429 | The \f(CW\*(C`#include\*(C'\fR statement is not really needed, because Inline | |
430 | automatically includes the Perl headers which include almost all | |
431 | standard system calls. | |
432 | .IP "See Also" 4 | |
433 | .IX Item "See Also" | |
434 | For more information on the Inline stack macros, see Inline::C. | |
435 | .IP "Credits" 4 | |
436 | .IX Item "Credits" | |
437 | Richard Anderson <starfire@zipcon.net> contributed the original idea for | |
438 | this snippet. | |
439 | .Sh "Multiple Return Values (Another Way)" | |
440 | .IX Subsection "Multiple Return Values (Another Way)" | |
441 | .IP "Problem" 4 | |
442 | .IX Item "Problem" | |
443 | How can I pass back more than one value without using the Perl Stack? | |
444 | .IP "Solution" 4 | |
445 | .IX Item "Solution" | |
446 | .Vb 2 | |
447 | \& use Inline::Files; | |
448 | \& use Inline C; | |
449 | .Ve | |
450 | .Sp | |
451 | .Vb 2 | |
452 | \& my ($foo, $bar); | |
453 | \& change($foo, $bar); | |
454 | .Ve | |
455 | .Sp | |
456 | .Vb 2 | |
457 | \& print "\e$foo = $foo\en"; | |
458 | \& print "\e$bar = $bar\en"; | |
459 | .Ve | |
460 | .Sp | |
461 | .Vb 1 | |
462 | \& __C__ | |
463 | .Ve | |
464 | .Sp | |
465 | .Vb 5 | |
466 | \& int change(SV* var1, SV* var2) { | |
467 | \& sv_setpvn(var1, "Perl Rocks!", 11); | |
468 | \& sv_setpvn(var2, "Inline Rules!", 13); | |
469 | \& return 1; | |
470 | \& } | |
471 | .Ve | |
472 | .IP "Discussion" 4 | |
473 | .IX Item "Discussion" | |
474 | Most perl function interfaces return values as a list of one or more | |
475 | scalars. Very few like \f(CW\*(C`chomp\*(C'\fR, will modify an input scalar in place. | |
476 | On the other hand, in C you do this quite often. Values are passed in by | |
477 | reference and modified in place by the called function. | |
478 | .Sp | |
479 | It turns out that we can do that with Inline as well. The secret is to | |
480 | use a type of '\f(CW\*(C`SV*\*(C'\fR' for each argument that is to be modified. This | |
481 | ensures passing by reference, because no typemapping is needed. | |
482 | .Sp | |
483 | The function can then use the Perl5 \s-1API\s0 to operate on that argument. | |
484 | When control returns to Perl, the argument will retain the value set by | |
485 | the C function. In this example we passed in 2 empty scalars and | |
486 | assigned values directly to them. | |
487 | .IP "See Also" 4 | |
488 | .IX Item "See Also" | |
489 | .PD 0 | |
490 | .IP "Credits" 4 | |
491 | .IX Item "Credits" | |
492 | .PD | |
493 | Ned Konz <ned@bike\-nomad.com> brought this behavior to my attention. He | |
494 | also pointed out that he is not the world famous computer cyclist Steve | |
495 | Roberts (http://www.microship.com), but he is close | |
496 | (http://bike\-nomad.com). Thanks Ned. | |
497 | .Sh "Using Memory" | |
498 | .IX Subsection "Using Memory" | |
499 | .IP "Problem" 4 | |
500 | .IX Item "Problem" | |
501 | How should I allocate buffers in my Inline C code? | |
502 | .IP "Solution" 4 | |
503 | .IX Item "Solution" | |
504 | .Vb 1 | |
505 | \& print greeting('Ingy'); | |
506 | .Ve | |
507 | .Sp | |
508 | .Vb 1 | |
509 | \& use Inline C => <<'END_OF_C_CODE'; | |
510 | .Ve | |
511 | .Sp | |
512 | .Vb 3 | |
513 | \& SV* greeting(SV* sv_name) { | |
514 | \& return (newSVpvf("Hello %s!\en", SvPV(sv_name, PL_na))); | |
515 | \& } | |
516 | .Ve | |
517 | .Sp | |
518 | .Vb 1 | |
519 | \& END_OF_C_CODE | |
520 | .Ve | |
521 | .IP "Discussion" 4 | |
522 | .IX Item "Discussion" | |
523 | In this example we will return the greeting to the caller, rather than | |
524 | printing it. This would seem mighty easy, except for the fact that we | |
525 | need to allocate a small buffer to create the greeting. | |
526 | .Sp | |
527 | I would urge you to stay away from \f(CW\*(C`malloc\*(C'\fRing your own buffer. Just | |
528 | use Perl's built in memory management. In other words, just create a new | |
529 | Perl string scalar. The function \f(CW\*(C`newSVpv\*(C'\fR does just that. And | |
530 | \&\f(CW\*(C`newSVpvf\*(C'\fR includes \f(CW\*(C`sprintf\*(C'\fR functionality. | |
531 | .Sp | |
532 | The other problem is getting rid of this new scalar. How will the ref | |
533 | count get decremented after we pass the scalar back? Perl also provides | |
534 | a function called \f(CW\*(C`sv_2mortal\*(C'\fR. Mortal variables die when the context | |
535 | goes out of scope. In other words, Perl will wait until the new scalar | |
536 | gets passed back and then decrement the ref count for you, thereby | |
537 | making it eligible for garbage collection. See \f(CW\*(C`perldoc perlguts\*(C'\fR. | |
538 | .Sp | |
539 | In this example the \f(CW\*(C`sv_2mortal\*(C'\fR call gets done under the hood by \s-1XS\s0, | |
540 | because we declared the return type to be \f(CW\*(C`SV*\*(C'\fR. | |
541 | .Sp | |
542 | To view the generated \s-1XS\s0 code, run the command "\f(CW\*(C`perl | |
543 | \&\-MInline=INFO,FORCE,NOCLEAN example004.pl\*(C'\fR". This will leave the build | |
544 | directory intact and tell you where to find it. | |
545 | .IP "See Also" 4 | |
546 | .IX Item "See Also" | |
547 | .PD 0 | |
548 | .IP "Credits" 4 | |
549 | .IX Item "Credits" | |
550 | .PD | |
551 | .SH "Fast Food" | |
552 | .IX Header "Fast Food" | |
553 | .Sh "Inline \s-1CGI\s0" | |
554 | .IX Subsection "Inline CGI" | |
555 | .IP "Problem" 4 | |
556 | .IX Item "Problem" | |
557 | How do I use Inline securely in a \s-1CGI\s0 environment? | |
558 | .IP "Solution" 4 | |
559 | .IX Item "Solution" | |
560 | .Vb 1 | |
561 | \& #!/usr/bin/perl | |
562 | .Ve | |
563 | .Sp | |
564 | .Vb 4 | |
565 | \& use CGI qw(:standard); | |
566 | \& use Inline (Config => | |
567 | \& DIRECTORY => '/usr/local/apache/Inline', | |
568 | \& ); | |
569 | .Ve | |
570 | .Sp | |
571 | .Vb 5 | |
572 | \& print (header, | |
573 | \& start_html('Inline CGI Example'), | |
574 | \& h1(JAxH('Inline')), | |
575 | \& end_html | |
576 | \& ); | |
577 | .Ve | |
578 | .Sp | |
579 | .Vb 5 | |
580 | \& use Inline C => <<END; | |
581 | \& SV* JAxH(char* x) { | |
582 | \& return newSVpvf("Just Another %s Hacker", x); | |
583 | \& } | |
584 | \& END | |
585 | .Ve | |
586 | .IP "Discussion" 4 | |
587 | .IX Item "Discussion" | |
588 | The problem with running Inline code from a \s-1CGI\s0 script is that Inline | |
589 | \&\fBwrites\fR to a build area on your disk whenever it compiles code. Most | |
590 | \&\s-1CGI\s0 scripts don't (and shouldn't) be able to create a directory and | |
591 | write into it. | |
592 | .Sp | |
593 | The solution is to explicitly tell Inline which directory to use with | |
594 | the 'use Inline Config => \s-1DIRECTORY\s0 => ...' line. Then you need to give | |
595 | write access to that directory from the web server (\s-1CGI\s0 script). | |
596 | .Sp | |
597 | If you see this as a security hole, then there is another option. | |
598 | Give write access to yourself, but read-only access to the \s-1CGI\s0 | |
599 | script. Then run the script once by hand (from the command line). | |
600 | This will cause Inline to precompile the C code. That way the \s-1CGI\s0 | |
601 | will only need read access to the build directory (to load in the | |
602 | shared library from there). | |
603 | .Sp | |
604 | Just remember that whenever you change the C code, you need to | |
605 | precompile it again. | |
606 | .IP "See Also" 4 | |
607 | .IX Item "See Also" | |
608 | See \s-1CGI\s0 for more information on using the \f(CW\*(C`CGI.pm\*(C'\fR module. | |
609 | .IP "Credits" 4 | |
610 | .IX Item "Credits" | |
611 | .Sh "mod_perl" | |
612 | .IX Subsection "mod_perl" | |
613 | .PD 0 | |
614 | .IP "Problem" 4 | |
615 | .IX Item "Problem" | |
616 | .PD | |
617 | How do I use Inline with mod_perl? | |
618 | .IP "Solution" 4 | |
619 | .IX Item "Solution" | |
620 | .Vb 7 | |
621 | \& package Factorial; | |
622 | \& use strict; | |
623 | \& use Inline Config => | |
624 | \& DIRECTORY => '/usr/local/apache/Inline', | |
625 | \& ENABLE => 'UNTAINT'; | |
626 | \& use Inline 'C'; | |
627 | \& Inline->init; | |
628 | .Ve | |
629 | .Sp | |
630 | .Vb 6 | |
631 | \& sub handler { | |
632 | \& my $r = shift; | |
633 | \& $r->send_http_header('text/plain'); | |
634 | \& printf "%3d! = %10d\en", $_, factorial($_) for 1..100; | |
635 | \& return Apache::Constants::OK; | |
636 | \& } | |
637 | .Ve | |
638 | .Sp | |
639 | .Vb 7 | |
640 | \& 1; | |
641 | \& __DATA__ | |
642 | \& __C__ | |
643 | \& double factorial(double x) { | |
644 | \& if (x < 2) return 1; | |
645 | \& return x * factorial(x - 1) | |
646 | \& } | |
647 | .Ve | |
648 | .IP "Discussion" 4 | |
649 | .IX Item "Discussion" | |
650 | This is a fully functional mod_perl handler that prints out the | |
651 | factorial values for the numbers 1 to 100. Since we are using Inline | |
652 | under mod_perl, there are a few considerations to , um, consider. | |
653 | .Sp | |
654 | First, mod_perl handlers are usually run with \f(CW\*(C`\-T\*(C'\fR taint detection. | |
655 | Therefore, we need to enable the \s-1UNTAINT\s0 option. The next thing to deal | |
656 | with is the fact that this handler will most likely be loaded after | |
657 | Perl's compile time. Since we are using the \s-1DATA\s0 section, we need to | |
658 | use the special \f(CW\*(C`init()\*(C'\fR call. And of course we need to specify a | |
659 | \&\s-1DIRECTORY\s0 that mod_perl can compile into. \fISee the above \s-1CGI\s0 example | |
660 | for more info.\fR | |
661 | .Sp | |
662 | Other than that, this is a pretty straightforward mod_perl handler, | |
663 | tuned for even more speed! | |
664 | .IP "See Also" 4 | |
665 | .IX Item "See Also" | |
666 | See Stas Bekman's upcoming O'Reilly book on mod_perl to which this | |
667 | example was contributed. | |
668 | .IP "Credits" 4 | |
669 | .IX Item "Credits" | |
670 | .Sh "Object Oriented Inline" | |
671 | .IX Subsection "Object Oriented Inline" | |
672 | .PD 0 | |
673 | .IP "Problem" 4 | |
674 | .IX Item "Problem" | |
675 | .PD | |
676 | How do I implement Object Oriented programming in Perl using C objects? | |
677 | .IP "Solution" 4 | |
678 | .IX Item "Solution" | |
679 | .Vb 3 | |
680 | \& my $obj1 = Soldier->new('Benjamin', 'Private', 11111); | |
681 | \& my $obj2 = Soldier->new('Sanders', 'Colonel', 22222); | |
682 | \& my $obj3 = Soldier->new('Matt', 'Sergeant', 33333); | |
683 | .Ve | |
684 | .Sp | |
685 | .Vb 5 | |
686 | \& for my $obj ($obj1, $obj2, $obj3) { | |
687 | \& print ($obj->get_serial, ") ", | |
688 | \& $obj->get_name, " is a ", | |
689 | \& $obj->get_rank, "\en"); | |
690 | \& } | |
691 | .Ve | |
692 | .Sp | |
693 | .Vb 1 | |
694 | \& #--------------------------------------------------------- | |
695 | .Ve | |
696 | .Sp | |
697 | .Vb 1 | |
698 | \& package Soldier; | |
699 | .Ve | |
700 | .Sp | |
701 | .Vb 1 | |
702 | \& use Inline C => <<'END'; | |
703 | .Ve | |
704 | .Sp | |
705 | .Vb 5 | |
706 | \& typedef struct { | |
707 | \& char* name; | |
708 | \& char* rank; | |
709 | \& long serial; | |
710 | \& } Soldier; | |
711 | .Ve | |
712 | .Sp | |
713 | .Vb 4 | |
714 | \& SV* new(char* class, char* name, char* rank, long serial) { | |
715 | \& Soldier* soldier = malloc(sizeof(Soldier)); | |
716 | \& SV* obj_ref = newSViv(0); | |
717 | \& SV* obj = newSVrv(obj_ref, class); | |
718 | .Ve | |
719 | .Sp | |
720 | .Vb 3 | |
721 | \& soldier->name = strdup(name); | |
722 | \& soldier->rank = strdup(rank); | |
723 | \& soldier->serial = serial; | |
724 | .Ve | |
725 | .Sp | |
726 | .Vb 4 | |
727 | \& sv_setiv(obj, (IV)soldier); | |
728 | \& SvREADONLY_on(obj); | |
729 | \& return obj_ref; | |
730 | \& } | |
731 | .Ve | |
732 | .Sp | |
733 | .Vb 3 | |
734 | \& char* get_name(SV* obj) { | |
735 | \& return ((Soldier*)SvIV(SvRV(obj)))->name; | |
736 | \& } | |
737 | .Ve | |
738 | .Sp | |
739 | .Vb 3 | |
740 | \& char* get_rank(SV* obj) { | |
741 | \& return ((Soldier*)SvIV(SvRV(obj)))->rank; | |
742 | \& } | |
743 | .Ve | |
744 | .Sp | |
745 | .Vb 3 | |
746 | \& long get_serial(SV* obj) { | |
747 | \& return ((Soldier*)SvIV(SvRV(obj)))->serial; | |
748 | \& } | |
749 | .Ve | |
750 | .Sp | |
751 | .Vb 7 | |
752 | \& void DESTROY(SV* obj) { | |
753 | \& Soldier* soldier = (Soldier*)SvIV(SvRV(obj)); | |
754 | \& free(soldier->name); | |
755 | \& free(soldier->rank); | |
756 | \& free(soldier); | |
757 | \& } | |
758 | \& END | |
759 | .Ve | |
760 | .IP "Discussion" 4 | |
761 | .IX Item "Discussion" | |
762 | Damian Conway has given us myriad ways of implementing \s-1OOP\s0 in Perl. This | |
763 | is one he might not have thought of. | |
764 | .Sp | |
765 | The interesting thing about this example is that it uses Perl for all | |
766 | the \s-1OO\s0 bindings while using C for the attributes and methods. | |
767 | .Sp | |
768 | If you examine the Perl code everything looks exactly like a regular \s-1OO\s0 | |
769 | example. There is a \f(CW\*(C`new\*(C'\fR method and several accessor methods. The | |
770 | familiar 'arrow syntax' is used to invoke them. | |
771 | .Sp | |
772 | In the class definition (second part) the Perl \f(CW\*(C`package\*(C'\fR statement is | |
773 | used to name the object class or namespace. But that's where the | |
774 | similarities end Inline takes over. | |
775 | .Sp | |
776 | The idea is that we call a C subroutine called \f(CW\*(C`new()\*(C'\fR which returns a | |
777 | blessed scalar. The scalar contains a readonly integer which is a C | |
778 | pointer to a Soldier struct. This is our object. | |
779 | .Sp | |
780 | The \f(CW\*(C`new()\*(C'\fR function needs to malloc the memory for the struct and then | |
781 | copy the initial values into it using \f(CW\*(C`strdup()\*(C'\fR. This also allocates | |
782 | more memory (which we have to keep track of). | |
783 | .Sp | |
784 | The accessor methods are pretty straightforward. They return the current | |
785 | value of their attribute. | |
786 | .Sp | |
787 | The last method \f(CW\*(C`DESTROY()\*(C'\fR is called automatically by Perl whenever an | |
788 | object goes out of scope. This is where we can free all the memory used | |
789 | by the object. | |
790 | .Sp | |
791 | That's it. It's a very simplistic example. It doesn't show off any | |
792 | advanced \s-1OO\s0 features, but it is pretty cool to see how easy the | |
793 | implementation can be. The important Perl call is \f(CW\*(C`newSVrv()\*(C'\fR which | |
794 | creates a blessed scalar. | |
795 | .IP "See Also" 4 | |
796 | .IX Item "See Also" | |
797 | Read \*(L"Object Oriented Perl\*(R" by Damian Conway, for more useful ways of | |
798 | doing \s-1OOP\s0 in Perl. | |
799 | .Sp | |
800 | You can learn more Perl calls in perlapi. If you don't have Perl | |
801 | 5.6.0 or higher, visit http://www.perldoc.com/perl5.6/pod/perlapi.html | |
802 | .IP "Credits" 4 | |
803 | .IX Item "Credits" | |
804 | .SH "The Main Course" | |
805 | .IX Header "The Main Course" | |
806 | .Sh "Exposing Shared Libraries" | |
807 | .IX Subsection "Exposing Shared Libraries" | |
808 | .PD 0 | |
809 | .IP "Problem" 4 | |
810 | .IX Item "Problem" | |
811 | .PD | |
812 | You have this great C library and you want to be able to access parts of | |
813 | it with Perl. | |
814 | .IP "Solution" 4 | |
815 | .IX Item "Solution" | |
816 | .Vb 1 | |
817 | \& print get('http://www.axkit.org'); | |
818 | .Ve | |
819 | .Sp | |
820 | .Vb 3 | |
821 | \& use Inline C => Config => | |
822 | \& LIBS => '-lghttp'; | |
823 | \& use Inline C => <<'END_OF_C_CODE'; | |
824 | .Ve | |
825 | .Sp | |
826 | .Vb 1 | |
827 | \& #include <ghttp.h> | |
828 | .Ve | |
829 | .Sp | |
830 | .Vb 3 | |
831 | \& char *get(SV* uri) { | |
832 | \& SV* buffer; | |
833 | \& ghttp_request* request; | |
834 | .Ve | |
835 | .Sp | |
836 | .Vb 3 | |
837 | \& buffer = NEWSV(0,0); | |
838 | \& request = ghttp_request_new(); | |
839 | \& ghttp_set_uri(request, SvPV(uri, PL_na)); | |
840 | .Ve | |
841 | .Sp | |
842 | .Vb 1 | |
843 | \& ghttp_set_header(request, http_hdr_Connection, "close"); | |
844 | .Ve | |
845 | .Sp | |
846 | .Vb 2 | |
847 | \& ghttp_prepare(request); | |
848 | \& ghttp_process(request); | |
849 | .Ve | |
850 | .Sp | |
851 | .Vb 1 | |
852 | \& sv_catpv(buffer, ghttp_get_body(request)); | |
853 | .Ve | |
854 | .Sp | |
855 | .Vb 1 | |
856 | \& ghttp_request_destroy(request); | |
857 | .Ve | |
858 | .Sp | |
859 | .Vb 2 | |
860 | \& return SvPV(buffer, PL_na); | |
861 | \& } | |
862 | .Ve | |
863 | .Sp | |
864 | .Vb 1 | |
865 | \& END_OF_C_CODE | |
866 | .Ve | |
867 | .IP "Discussion" 4 | |
868 | .IX Item "Discussion" | |
869 | This example fetches and prints the \s-1HTML\s0 from http://www.axkit.org | |
870 | It requires the \s-1GNOME\s0 http libraries. http://www.gnome.org | |
871 | .Sp | |
872 | One of the most common questions I get is \*(L"How can I use Inline to make | |
873 | use of some shared library?\*(R". Although it has always been possible to do | |
874 | so, the configuration was ugly, and there were no specific examples. | |
875 | .Sp | |
876 | With version 0.30 and higher, you can specify the use of shared | |
877 | libraries easily with something like this: | |
878 | .Sp | |
879 | .Vb 2 | |
880 | \& use Inline C => Config => LIBS => '-lghttp'; | |
881 | \& use Inline C => "code ..."; | |
882 | .Ve | |
883 | .Sp | |
884 | or | |
885 | .Sp | |
886 | .Vb 1 | |
887 | \& use Inline C => "code ...", LIBS => '-lghttp'; | |
888 | .Ve | |
889 | .Sp | |
890 | To specify a specific library path, use: | |
891 | .Sp | |
892 | .Vb 1 | |
893 | \& use Inline C => "code ...", LIBS => '-L/your/lib/path -lyourlib'; | |
894 | .Ve | |
895 | .Sp | |
896 | To specify an include path use: | |
897 | .Sp | |
898 | .Vb 3 | |
899 | \& use Inline C => "code ...", | |
900 | \& LIBS => '-lghttp', | |
901 | \& INC => '-I/your/inc/path'; | |
902 | .Ve | |
903 | .IP "See Also" 4 | |
904 | .IX Item "See Also" | |
905 | The \f(CW\*(C`LIBS\*(C'\fR and \f(CW\*(C`INC\*(C'\fR configuration options are formatted and passed | |
906 | into MakeMaker. For more info see ExtUtils::MakeMaker. For more | |
907 | options see Inline::C. | |
908 | .IP "Credits" 4 | |
909 | .IX Item "Credits" | |
910 | This code was written by Matt Sergeant <matt@sergeant.org>, author of | |
911 | many \s-1CPAN\s0 modules. The configuration syntax has been modified for use | |
912 | with Inline v0.30. | |
913 | .Sh "Automatic Function Wrappers" | |
914 | .IX Subsection "Automatic Function Wrappers" | |
915 | .IP "Problem" 4 | |
916 | .IX Item "Problem" | |
917 | You have some functions in a C library that you want to access from Perl | |
918 | exactly as you would from C. | |
919 | .IP "Solution" 4 | |
920 | .IX Item "Solution" | |
921 | The error function \f(CW\*(C`erf()\*(C'\fR is probably defined in your standard math | |
922 | library. Annoyingly, Perl does not let you access it. To print out a | |
923 | small table of its values, just say: | |
924 | .Sp | |
925 | .Vb 1 | |
926 | \& perl -le 'use Inline C => q{ double erf(double); }, ENABLE => "AUTOWRAP"; print "$_ @{[erf($_)]}" for (0..10)' | |
927 | .Ve | |
928 | .Sp | |
929 | The excellent \f(CW\*(C`Term::ReadLine::Gnu\*(C'\fR implements Term::ReadLine using the | |
930 | \&\s-1GNU\s0 ReadLine library. Here is an easy way to access just \f(CW\*(C`readline()\*(C'\fR | |
931 | from that library: | |
932 | .Sp | |
933 | .Vb 1 | |
934 | \& package MyTerm; | |
935 | .Ve | |
936 | .Sp | |
937 | .Vb 4 | |
938 | \& use Inline C => Config => | |
939 | \& ENABLE => AUTOWRAP => | |
940 | \& LIBS => "-lreadline -lncurses -lterminfo -ltermcap "; | |
941 | \& use Inline C => q{ char * readline(char *); }; | |
942 | .Ve | |
943 | .Sp | |
944 | .Vb 2 | |
945 | \& package main; | |
946 | \& my $x = MyTerm::readline("xyz: "); | |
947 | .Ve | |
948 | .Sp | |
949 | Note however that it fails to \f(CW\*(C`free()\*(C'\fR the memory returned by readline, | |
950 | and that \f(CW\*(C`Term::ReadLine::Gnu\*(C'\fR offers a much richer interface. | |
951 | .IP "Discussion" 4 | |
952 | .IX Item "Discussion" | |
953 | We access existing functions by merely showing Inline their | |
954 | declarations, rather than a full definition. Of course the function | |
955 | declared must exist, either in a library already linked to Perl or in a | |
956 | library specified using the \f(CW\*(C`LIBS\*(C'\fR option. | |
957 | .Sp | |
958 | The first example wraps a function from the standard math library, so | |
959 | Inline requires no additional \f(CW\*(C`LIBS\*(C'\fR directive. The second uses the | |
960 | Config option to specify the libraries that contain the actual | |
961 | compiled C code. | |
962 | .Sp | |
963 | This behavior is always disabled by default. You must enable the | |
964 | \&\f(CW\*(C`AUTOWRAP\*(C'\fR option to make it work. | |
965 | .IP "See Also" 4 | |
966 | .IX Item "See Also" | |
967 | \&\f(CW\*(C`readline\*(C'\fR, \f(CW\*(C`Term::ReadLine::Gnu\*(C'\fR | |
968 | .IP "Credits" 4 | |
969 | .IX Item "Credits" | |
970 | \&\s-1GNU\s0 ReadLine was written by Brian Fox <bfox@ai.mit.edu> and Chet Ramey | |
971 | <chet@ins.cwru.edu>. Term::ReadLine::Gnu was written by Hiroo Hayashi | |
972 | <hiroo.hayashi@computer.org>. Both are far richer than the slim | |
973 | interface given here! | |
974 | .Sp | |
975 | The idea of producing wrapper code given only a function declaration is | |
976 | taken from Swig by David M. Beazley <beazley@cs.uchicago.edu>. | |
977 | .Sp | |
978 | Ingy's inline editorial insight: | |
979 | .Sp | |
980 | This entire entry was contributed by Ariel Scolnicov | |
981 | <ariels@compugen.co.il>. Ariel also first suggested the idea for Inline | |
982 | to support function declaration processing. | |
983 | .Sh "Complex Data" | |
984 | .IX Subsection "Complex Data" | |
985 | .IP "Problem" 4 | |
986 | .IX Item "Problem" | |
987 | How do I deal with complex data types like hashes in Inline C? | |
988 | .IP "Solution" 4 | |
989 | .IX Item "Solution" | |
990 | .Vb 1 | |
991 | \& use Inline C => <<'END_OF_C_CODE'; | |
992 | .Ve | |
993 | .Sp | |
994 | .Vb 6 | |
995 | \& void dump_hash(SV* hash_ref) { | |
996 | \& HV* hash; | |
997 | \& HE* hash_entry; | |
998 | \& int num_keys, i; | |
999 | \& SV* sv_key; | |
1000 | \& SV* sv_val; | |
1001 | .Ve | |
1002 | .Sp | |
1003 | .Vb 2 | |
1004 | \& if (! SvROK(hash_ref)) | |
1005 | \& croak("hash_ref is not a reference"); | |
1006 | .Ve | |
1007 | .Sp | |
1008 | .Vb 10 | |
1009 | \& hash = (HV*)SvRV(hash_ref); | |
1010 | \& num_keys = hv_iterinit(hash); | |
1011 | \& for (i = 0; i < num_keys; i++) { | |
1012 | \& hash_entry = hv_iternext(hash); | |
1013 | \& sv_key = hv_iterkeysv(hash_entry); | |
1014 | \& sv_val = hv_iterval(hash, hash_entry); | |
1015 | \& printf("%s => %s\en", SvPV(sv_key, PL_na), SvPV(sv_val, PL_na)); | |
1016 | \& } | |
1017 | \& return; | |
1018 | \& } | |
1019 | .Ve | |
1020 | .Sp | |
1021 | .Vb 1 | |
1022 | \& END_OF_C_CODE | |
1023 | .Ve | |
1024 | .Sp | |
1025 | .Vb 7 | |
1026 | \& my %hash = ( | |
1027 | \& Author => "Brian Ingerson", | |
1028 | \& Nickname => "INGY", | |
1029 | \& Module => "Inline.pm", | |
1030 | \& Version => "0.30", | |
1031 | \& Language => "C", | |
1032 | \& ); | |
1033 | .Ve | |
1034 | .Sp | |
1035 | .Vb 1 | |
1036 | \& dump_hash(\e%hash); | |
1037 | .Ve | |
1038 | .IP "Discussion" 4 | |
1039 | .IX Item "Discussion" | |
1040 | The world is not made of scalars alone, although they are definitely | |
1041 | the easiest creatures to deal with, when doing Inline stuff. | |
1042 | Sometimes we need to deal with arrays, hashes, and code references, | |
1043 | among other things. | |
1044 | .Sp | |
1045 | Since Perl subroutine calls only pass scalars as arguments, we'll | |
1046 | need to use the argument type \f(CW\*(C`SV*\*(C'\fR and pass references to more | |
1047 | complex types. | |
1048 | .Sp | |
1049 | The above program dumps the key/value pairs of a hash. To figure it out, | |
1050 | just curl up with perlapi for a couple hours. Actually, its fairly | |
1051 | straight forward once you are familiar with the calls. | |
1052 | .Sp | |
1053 | Note the \f(CW\*(C`croak\*(C'\fR function call. This is the proper way to die from your | |
1054 | C extensions. | |
1055 | .IP "See Also" 4 | |
1056 | .IX Item "See Also" | |
1057 | See perlapi for information about the Perl5 internal \s-1API\s0. | |
1058 | .IP "Credits" 4 | |
1059 | .IX Item "Credits" | |
1060 | .Sh "Hash of Lists" | |
1061 | .IX Subsection "Hash of Lists" | |
1062 | .PD 0 | |
1063 | .IP "Problem" 4 | |
1064 | .IX Item "Problem" | |
1065 | .PD | |
1066 | How do I create a Hash of Lists from C? | |
1067 | .IP "Solution" 4 | |
1068 | .IX Item "Solution" | |
1069 | .Vb 2 | |
1070 | \& use Inline C; | |
1071 | \& use Data::Dumper; | |
1072 | .Ve | |
1073 | .Sp | |
1074 | .Vb 2 | |
1075 | \& $hash_ref = load_data("./cartoon.txt"); | |
1076 | \& print Dumper $hash_ref; | |
1077 | .Ve | |
1078 | .Sp | |
1079 | .Vb 2 | |
1080 | \& __END__ | |
1081 | \& __C__ | |
1082 | .Ve | |
1083 | .Sp | |
1084 | .Vb 1 | |
1085 | \& static int next_word(char**, char*); | |
1086 | .Ve | |
1087 | .Sp | |
1088 | .Vb 5 | |
1089 | \& SV* load_data(char* file_name) { | |
1090 | \& char buffer[100], word[100], * pos; | |
1091 | \& AV* array; | |
1092 | \& HV* hash = newHV(); | |
1093 | \& FILE* fh = fopen(file_name, "r"); | |
1094 | .Ve | |
1095 | .Sp | |
1096 | .Vb 11 | |
1097 | \& while (fgets(pos = buffer, sizeof(buffer), fh)) { | |
1098 | \& if (next_word(&pos, word)) { | |
1099 | \& hv_store(hash, word, strlen(word), | |
1100 | \& newRV_noinc((SV*)array = newAV()), 0); | |
1101 | \& while (next_word(&pos, word)) | |
1102 | \& av_push(array, newSVpvf("%s", word)); | |
1103 | \& } | |
1104 | \& } | |
1105 | \& fclose(fh); | |
1106 | \& return newRV_noinc((SV*) hash); | |
1107 | \& } | |
1108 | .Ve | |
1109 | .Sp | |
1110 | .Vb 15 | |
1111 | \& static int next_word(char** text_ptr, char* word) { | |
1112 | \& char* text = *text_ptr; | |
1113 | \& while(*text != '\e0' && | |
1114 | \& *text <= ' ') | |
1115 | \& text++; | |
1116 | \& if (*text <= ' ') | |
1117 | \& return 0; | |
1118 | \& while(*text != '\e0' && | |
1119 | \& *text > ' ') { | |
1120 | \& *word++ = *text++; | |
1121 | \& } | |
1122 | \& *word = '\e0'; | |
1123 | \& *text_ptr = text; | |
1124 | \& return 1; | |
1125 | \& } | |
1126 | .Ve | |
1127 | .IP "Discussion" 4 | |
1128 | .IX Item "Discussion" | |
1129 | This is one of the larger recipes. But when you consider the number of | |
1130 | calories it has, it's not so bad. The function \f(CW\*(C`load_data\*(C'\fR takes the | |
1131 | name of a file as it's input. The file \f(CW\*(C`cartoon.text\*(C'\fR might look like: | |
1132 | .Sp | |
1133 | .Vb 3 | |
1134 | \& flintstones fred barney | |
1135 | \& jetsons george jane elroy | |
1136 | \& simpsons homer marge bart | |
1137 | .Ve | |
1138 | .Sp | |
1139 | The function will read the file, parsing each line into words. Then it | |
1140 | will create a new hash, whereby the first word in a line becomes a hash | |
1141 | key and the remaining words are put into an array whose reference | |
1142 | becomes the hash value. The output looks like this: | |
1143 | .Sp | |
1144 | .Vb 16 | |
1145 | \& $VAR1 = { | |
1146 | \& 'flintstones' => [ | |
1147 | \& 'fred', | |
1148 | \& 'barney' | |
1149 | \& ], | |
1150 | \& 'simpsons' => [ | |
1151 | \& 'homer', | |
1152 | \& 'marge', | |
1153 | \& 'bart' | |
1154 | \& ], | |
1155 | \& 'jetsons' => [ | |
1156 | \& 'george', | |
1157 | \& 'jane', | |
1158 | \& 'elroy' | |
1159 | \& ] | |
1160 | \& }; | |
1161 | .Ve | |
1162 | .IP "See Also" 4 | |
1163 | .IX Item "See Also" | |
1164 | See perlapi for information about the Perl5 internal \s-1API\s0. | |
1165 | .IP "Credits" 4 | |
1166 | .IX Item "Credits" | |
1167 | Al Danial <alnd@pacbell.net> requested a solution to this on | |
1168 | comp.lang.perl.misc. He borrowed the idea from the \*(L"Hash of Lists\*(R" | |
1169 | example in the Camel book. | |
1170 | .SH "Just Desserts" | |
1171 | .IX Header "Just Desserts" | |
1172 | .Sh "Win32" | |
1173 | .IX Subsection "Win32" | |
1174 | .IP "Problem" 4 | |
1175 | .IX Item "Problem" | |
1176 | How do I access Win32 DLL-s using Inline? | |
1177 | .IP "Solution" 4 | |
1178 | .IX Item "Solution" | |
1179 | .Vb 2 | |
1180 | \& use Inline C => DATA => | |
1181 | \& LIBS => '-luser32'; | |
1182 | .Ve | |
1183 | .Sp | |
1184 | .Vb 1 | |
1185 | \& $text = "@ARGV" || 'Inline.pm works with MSWin32. Scary...'; | |
1186 | .Ve | |
1187 | .Sp | |
1188 | .Vb 1 | |
1189 | \& WinBox('Inline Text Box', $text); | |
1190 | .Ve | |
1191 | .Sp | |
1192 | .Vb 2 | |
1193 | \& __END__ | |
1194 | \& __C__ | |
1195 | .Ve | |
1196 | .Sp | |
1197 | .Vb 1 | |
1198 | \& #include <windows.h> | |
1199 | .Ve | |
1200 | .Sp | |
1201 | .Vb 3 | |
1202 | \& int WinBox(char* Caption, char* Text) { | |
1203 | \& return MessageBoxA(0, Text, Caption, 0); | |
1204 | \& } | |
1205 | .Ve | |
1206 | .IP "Discussion" 4 | |
1207 | .IX Item "Discussion" | |
1208 | This example runs on \s-1MS\s0 Windows. It makes a text box appear on the | |
1209 | screen which contains a message of your choice. | |
1210 | .Sp | |
1211 | The important thing is that its proof that you can use Inline to | |
1212 | interact with Windows DLL\-s. Very scary indeed. 8\-o | |
1213 | .Sp | |
1214 | To use Inline on Windows with ActivePerl ( http://www.ActiveState.com ) | |
1215 | you'll need \s-1MS\s0 Visual Studio. You can also use the Cygwin environment, | |
1216 | available at http://www.cygwin.com . | |
1217 | .IP "See Also" 4 | |
1218 | .IX Item "See Also" | |
1219 | See Inline-Support for more info on MSWin32 programming with Inline. | |
1220 | .IP "Credits" 4 | |
1221 | .IX Item "Credits" | |
1222 | This example was adapted from some sample code written by Garrett Goebel | |
1223 | <garrett@scriptpro.com> | |
1224 | .Sh "Embedding Perl in C" | |
1225 | .IX Subsection "Embedding Perl in C" | |
1226 | .IP "Problem" 4 | |
1227 | .IX Item "Problem" | |
1228 | How do I use Perl from a regular C program? | |
1229 | .IP "Solution" 4 | |
1230 | .IX Item "Solution" | |
1231 | .Vb 1 | |
1232 | \& #!/usr/bin/cpr | |
1233 | .Ve | |
1234 | .Sp | |
1235 | .Vb 1 | |
1236 | \& int main(void) { | |
1237 | .Ve | |
1238 | .Sp | |
1239 | .Vb 2 | |
1240 | \& printf("Using Perl version %s from a C program!\en\en", | |
1241 | \& CPR_eval("use Config; $Config{version};")); | |
1242 | .Ve | |
1243 | .Sp | |
1244 | .Vb 2 | |
1245 | \& CPR_eval("use Data::Dumper;"); | |
1246 | \& CPR_eval("print Dumper \e\e%INC;"); | |
1247 | .Ve | |
1248 | .Sp | |
1249 | .Vb 1 | |
1250 | \& return 0; | |
1251 | .Ve | |
1252 | .Sp | |
1253 | .Vb 1 | |
1254 | \& } | |
1255 | .Ve | |
1256 | .IP "Discussion" 4 | |
1257 | .IX Item "Discussion" | |
1258 | By using \s-1CPR\s0. (C Perl Run) | |
1259 | .Sp | |
1260 | This example uses another Inline module, \f(CW\*(C`Inline::CPR\*(C'\fR, available | |
1261 | separately on \s-1CPAN\s0. When you install this module it also installs a | |
1262 | binary interpreter called \f(CW\*(C`/usr/bin/cpr\*(C'\fR. (The path may be different on | |
1263 | your system) | |
1264 | .Sp | |
1265 | When you feed a C program to the \s-1CPR\s0 interpreter, it automatically | |
1266 | compiles and runs your code using Inline. This gives you full access to | |
1267 | the Perl internals. \s-1CPR\s0 also provides a set of easy to use C macros for | |
1268 | calling Perl internals. | |
1269 | .Sp | |
1270 | This means that you can effectively \*(L"run\*(R" C source code by putting a \s-1CPR\s0 | |
1271 | hashbang as the first line of your C program. | |
1272 | .IP "See Also" 4 | |
1273 | .IX Item "See Also" | |
1274 | See Inline::CPR for more information on using \s-1CPR\s0. | |
1275 | .Sp | |
1276 | \&\f(CW\*(C`Inline::CPR\*(C'\fR can be obtained from | |
1277 | http://search.cpan.org/search?dist=Inline\-CPR | |
1278 | .IP "Credits" 4 | |
1279 | .IX Item "Credits" | |
1280 | Randal Schwartz <merlyn@stonehenge.com>, Randolph Bentson | |
1281 | <bentson@grieg.holmsjoen.com>, Richard Anderson <starfire@zipcon.net>, | |
1282 | and Tim Maher <tim@consultix\-inc.com> helped me figure out how to write | |
1283 | a program that would work as a hashbang. | |
1284 | .SH "Entertaining Guests" | |
1285 | .IX Header "Entertaining Guests" | |
1286 | As of version 0.30, Inline has the ability to work in cooperation with | |
1287 | other modules that want to expose a C \s-1API\s0 of their own. The general | |
1288 | syntax for doing this is: | |
1289 | .PP | |
1290 | .Vb 2 | |
1291 | \& use Inline with => 'Module'; | |
1292 | \& use Inline C => ... ; | |
1293 | .Ve | |
1294 | .PP | |
1295 | This tells \f(CW\*(C`Module\*(C'\fR to pass configuration options to Inline. Options | |
1296 | like typemaps, include paths, and external libraries, are all resolved | |
1297 | automatically so you can just concentrate on writing the functions. | |
1298 | .Sh "Event handling with Event.pm" | |
1299 | .IX Subsection "Event handling with Event.pm" | |
1300 | .IP "Problem" 4 | |
1301 | .IX Item "Problem" | |
1302 | You need to write a C callback for the \f(CW\*(C`Event.pm\*(C'\fR module. Can this be | |
1303 | done more easily with Inline? | |
1304 | .IP "Solution" 4 | |
1305 | .IX Item "Solution" | |
1306 | .Vb 1 | |
1307 | \& use Inline with => 'Event'; | |
1308 | .Ve | |
1309 | .Sp | |
1310 | .Vb 4 | |
1311 | \& Event->timer(desc => 'Timer #1', | |
1312 | \& interval => 2, | |
1313 | \& cb => \e&my_callback, | |
1314 | \& ); | |
1315 | .Ve | |
1316 | .Sp | |
1317 | .Vb 4 | |
1318 | \& Event->timer(desc => 'Timer #2', | |
1319 | \& interval => 3, | |
1320 | \& cb => \e&my_callback, | |
1321 | \& ); | |
1322 | .Ve | |
1323 | .Sp | |
1324 | .Vb 2 | |
1325 | \& print "Starting...\en"; | |
1326 | \& Event::loop; | |
1327 | .Ve | |
1328 | .Sp | |
1329 | .Vb 3 | |
1330 | \& use Inline C => <<'END'; | |
1331 | \& void my_callback(pe_event* event) { | |
1332 | \& pe_timer * watcher = event->up; | |
1333 | .Ve | |
1334 | .Sp | |
1335 | .Vb 7 | |
1336 | \& printf("%s\en\etEvent priority = %d\en\etWatcher priority = %d\en\en", | |
1337 | \& SvPVX(watcher->base.desc), | |
1338 | \& event->prio, | |
1339 | \& watcher->base.prio | |
1340 | \& ); | |
1341 | \& } | |
1342 | \& END | |
1343 | .Ve | |
1344 | .IP "Discussion" 4 | |
1345 | .IX Item "Discussion" | |
1346 | The first line tells Inline to load the \f(CW\*(C`Event.pm\*(C'\fR module. Inline then | |
1347 | queries \f(CW\*(C`Event\*(C'\fR for configuration information. It gets the name and | |
1348 | location of Event's header files, typemaps and shared objects. The | |
1349 | parameters that \f(CW\*(C`Event\*(C'\fR returns look like: | |
1350 | .Sp | |
1351 | .Vb 5 | |
1352 | \& INC => "-I $path/Event", | |
1353 | \& TYPEMAPS => "$path/Event/typemap", | |
1354 | \& MYEXTLIB => "$path/auto/Event/Event.$so", | |
1355 | \& AUTO_INCLUDE => '#include "EventAPI.h"', | |
1356 | \& BOOT => 'I_EVENT_API("Inline");', | |
1357 | .Ve | |
1358 | .Sp | |
1359 | Doing all of this automatically allows you, the programmer, to simply | |
1360 | write a function that receives a pointer of type \f(CW'pe_event*'\fR. This | |
1361 | gives you access to the \f(CW\*(C`Event\*(C'\fR structure that was passed to you. | |
1362 | .Sp | |
1363 | In this example, I simply print values out of the structure. The Perl | |
1364 | code defines 2 timer events which each invoke the same callback. The | |
1365 | first one, every two seconds, and the second one, every three seconds. | |
1366 | .Sp | |
1367 | As of this writing, \f(CW\*(C`Event.pm\*(C'\fR is the only \s-1CPAN\s0 module that works in | |
1368 | cooperation with Inline. | |
1369 | .IP "See Also" 4 | |
1370 | .IX Item "See Also" | |
1371 | Read the \f(CW\*(C`Event.pm\*(C'\fR documentation for more information. It contains a | |
1372 | tutorial showing several examples of using Inline with \f(CW\*(C`Event\*(C'\fR. | |
1373 | .IP "Credits" 4 | |
1374 | .IX Item "Credits" | |
1375 | Jochen Stenzel <perl@jochen\-stenzel.de> originally came up with the idea | |
1376 | of mixing Inline and \f(CW\*(C`Event\*(C'\fR. He also authored the \f(CW\*(C`Event\*(C'\fR tutorial. | |
1377 | .Sp | |
1378 | Joshua Pritikin <joshua.pritikin@db.com> is the author of \f(CW\*(C`Event.pm\*(C'\fR. | |
1379 | .SH "Food for Thought" | |
1380 | .IX Header "Food for Thought" | |
1381 | .Sh "Calling C from both Perl and C" | |
1382 | .IX Subsection "Calling C from both Perl and C" | |
1383 | .IP "Problem" 4 | |
1384 | .IX Item "Problem" | |
1385 | I'd like to be able to call the same C function from both Perl and C. | |
1386 | Also I like to define a C function that \fBdoesn't\fR get bound to Perl. | |
1387 | How do I do that? | |
1388 | .IP "Solution" 4 | |
1389 | .IX Item "Solution" | |
1390 | .Vb 3 | |
1391 | \& print "9 + 5 = ", add(9, 5), "\en"; | |
1392 | \& print "SQRT(9^2 + 5^2) = ", pyth(9, 5), "\en"; | |
1393 | \& print "9 * 5 = ", mult(9, 5), "\en"; | |
1394 | .Ve | |
1395 | .Sp | |
1396 | .Vb 11 | |
1397 | \& use Inline C => <<'END_C'; | |
1398 | \& int add(int x, int y) { | |
1399 | \& return x + y; | |
1400 | \& } | |
1401 | \& static int mult(int x, int y) { | |
1402 | \& return x * y; | |
1403 | \& } | |
1404 | \& double pyth(int x, int y) { | |
1405 | \& return sqrt(add(mult(x, x), mult(y, y))); | |
1406 | \& } | |
1407 | \& END_C | |
1408 | .Ve | |
1409 | .IP "Discussion" 4 | |
1410 | .IX Item "Discussion" | |
1411 | The program produces: | |
1412 | .Sp | |
1413 | .Vb 3 | |
1414 | \& 9 + 5 = 14 | |
1415 | \& SQRT(9^2 + 5^2) = 10.295630140987 | |
1416 | \& Can't locate auto/main/mult.al in @INC ... | |
1417 | .Ve | |
1418 | .Sp | |
1419 | Every Inline function that is bound to Perl is also callable by C. You | |
1420 | don't have to do anything special. Inline arranges it so that all the | |
1421 | typemap code gets done by \s-1XS\s0 and is out of sight. By the time the C | |
1422 | function receives control, everything has been converted from Perl to C. | |
1423 | .Sp | |
1424 | Of course if your function manipulates the Perl Stack, you | |
1425 | probably don't want to call it from C (unless you \fIreally\fR know | |
1426 | what you're doing). | |
1427 | .Sp | |
1428 | If you declare a function as \f(CW\*(C`static\*(C'\fR, Inline won't bind it to Perl. | |
1429 | That's why we were able to call \f(CW\*(C`mult()\*(C'\fR from C but the call failed | |
1430 | from Perl. | |
1431 | .IP "See Also" 4 | |
1432 | .IX Item "See Also" | |
1433 | .PD 0 | |
1434 | .IP "Credits" 4 | |
1435 | .IX Item "Credits" | |
1436 | .PD | |
1437 | .Sh "Calling Perl from C" | |
1438 | .IX Subsection "Calling Perl from C" | |
1439 | .IP "Problem" 4 | |
1440 | .IX Item "Problem" | |
1441 | So now that I can call C from Perl, how do I call a Perl subroutine from | |
1442 | an Inline C function. | |
1443 | .IP "Solution" 4 | |
1444 | .IX Item "Solution" | |
1445 | .Vb 1 | |
1446 | \& use Inline C; | |
1447 | .Ve | |
1448 | .Sp | |
1449 | .Vb 2 | |
1450 | \& c_func_1('This is the first line'); | |
1451 | \& c_func_2('This is the second line'); | |
1452 | .Ve | |
1453 | .Sp | |
1454 | .Vb 3 | |
1455 | \& sub perl_sub_1 { | |
1456 | \& print map "$_\en", @_; | |
1457 | \& } | |
1458 | .Ve | |
1459 | .Sp | |
1460 | .Vb 2 | |
1461 | \& __DATA__ | |
1462 | \& __C__ | |
1463 | .Ve | |
1464 | .Sp | |
1465 | .Vb 3 | |
1466 | \& void c_func_1(SV* text) { | |
1467 | \& c_func_2(text); | |
1468 | \& } | |
1469 | .Ve | |
1470 | .Sp | |
1471 | .Vb 7 | |
1472 | \& void c_func_2(SV* text) { | |
1473 | \& Inline_Stack_Vars; | |
1474 | \& Inline_Stack_Push(newSVpvf("Plus an extra line")); | |
1475 | \& Inline_Stack_Done; | |
1476 | \& perl_call_pv("main::perl_sub_1", 0); | |
1477 | \& Inline_Stack_Void; | |
1478 | \& } | |
1479 | .Ve | |
1480 | .IP "Discussion" 4 | |
1481 | .IX Item "Discussion" | |
1482 | Actually, this program demonstrates calling a C function which calls | |
1483 | another C function which in turn calls a Perl subroutine. | |
1484 | .Sp | |
1485 | The nice thing about Inline C functions is that you can call them from | |
1486 | both Perl-space \fBand\fR C\-space. That's because Inline creates a wrapper | |
1487 | function around each C function. When you use Perl to call C you're | |
1488 | actually calling that function's wrapper. The wrapper handles | |
1489 | typemapping and Stack management, and then calls your C function. | |
1490 | .Sp | |
1491 | The first time we call \f(CW\*(C`c_func_1\*(C'\fR which calls \f(CW\*(C`c_func_2\*(C'\fR. The second | |
1492 | time we call \f(CW\*(C`c_func_2\*(C'\fR directly. \f(CW\*(C`c_func_2\*(C'\fR calls the Perl subroutine | |
1493 | (\f(CW\*(C`perl_sub_1\*(C'\fR) using the internal \f(CW\*(C`perl_call_pv\*(C'\fR function. It has to | |
1494 | put arguments on the stack by hand. Since there is already one argument | |
1495 | on the stack when we enter the function, the \f(CW\*(C`Inline_Stack_Push\*(C'\fR adds a | |
1496 | second argument. \f(CW\*(C`Inline_Stack_Void\*(C'\fR makes sure that nothing is | |
1497 | returned from the function. | |
1498 | .IP "See Also" 4 | |
1499 | .IX Item "See Also" | |
1500 | See Inline::C for more information about Stack macros. | |
1501 | .Sp | |
1502 | See perlapi for more information about the Perl5 internal \s-1API\s0. | |
1503 | .IP "Credits" 4 | |
1504 | .IX Item "Credits" | |
1505 | .Sh "Evaling C" | |
1506 | .IX Subsection "Evaling C" | |
1507 | .PD 0 | |
1508 | .IP "Problem" 4 | |
1509 | .IX Item "Problem" | |
1510 | .PD | |
1511 | I've totally lost my marbles and I want to generate C code at run time, | |
1512 | and \f(CW\*(C`eval\*(C'\fR it into Perl. How do I do this? | |
1513 | .IP "Solution" 4 | |
1514 | .IX Item "Solution" | |
1515 | .Vb 2 | |
1516 | \& use Inline; | |
1517 | \& use Code::Generator; | |
1518 | .Ve | |
1519 | .Sp | |
1520 | .Vb 1 | |
1521 | \& my $c_code = generate('foo_function'); | |
1522 | .Ve | |
1523 | .Sp | |
1524 | .Vb 1 | |
1525 | \& Inline->bind(C => $c_code); | |
1526 | .Ve | |
1527 | .Sp | |
1528 | .Vb 1 | |
1529 | \& foo_function(1, 2, 3); | |
1530 | .Ve | |
1531 | .IP "Discussion" 4 | |
1532 | .IX Item "Discussion" | |
1533 | I can't think of a real life application where you would want to | |
1534 | generate C code on the fly, but at least I know know how I would do it. | |
1535 | :) | |
1536 | .Sp | |
1537 | The \f(CW\*(C`bind()\*(C'\fR function of Inline let's you bind (compile/load/execute) C | |
1538 | functions at run time. It takes all of the same arguments as 'use Inline | |
1539 | C => ...'. | |
1540 | .Sp | |
1541 | The nice thing is that once a particular snippet is compiled, it remains | |
1542 | cached so that it doesn't need to be compiled again. I can imagine that | |
1543 | someday a mad scientist will dream up a self generating modeling system | |
1544 | that would run faster and faster over time. | |
1545 | .Sp | |
1546 | If you know such a person, have them drop me a line. | |
1547 | .IP "See Also" 4 | |
1548 | .IX Item "See Also" | |
1549 | .PD 0 | |
1550 | .IP "Credits" 4 | |
1551 | .IX Item "Credits" | |
1552 | .PD | |
1553 | .SH "SEE ALSO" | |
1554 | .IX Header "SEE ALSO" | |
1555 | For generic information about Inline, see Inline. | |
1556 | .PP | |
1557 | For information about using Inline with C see Inline::C. | |
1558 | .PP | |
1559 | For information on supported languages and platforms see | |
1560 | Inline-Support. | |
1561 | .PP | |
1562 | For information on writing your own Inline language support module, see | |
1563 | Inline-API. | |
1564 | .PP | |
1565 | Inline's mailing list is inline@perl.org | |
1566 | .PP | |
1567 | To subscribe, send email to inline\-subscribe@perl.org | |
1568 | .SH "AUTHOR" | |
1569 | .IX Header "AUTHOR" | |
1570 | Brian Ingerson <INGY@cpan.org> | |
1571 | .SH "COPYRIGHT" | |
1572 | .IX Header "COPYRIGHT" | |
1573 | Copyright (c) 2001, 2002, Brian Ingerson. | |
1574 | .PP | |
1575 | All Rights Reserved. This module is free software. It may be | |
1576 | used, redistributed and/or modified under the terms of the Perl | |
1577 | Artistic License. | |
1578 | .PP | |
1579 | See http://www.perl.com/perl/misc/Artistic.html |