⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch26.htm

📁 《Perl 5 Unreleased》
💻 HTM
📖 第 1 页 / 共 5 页
字号:
variable set to a constant value will probably let <TT><FONT FACE="Courier">make</FONT></TT>

process the makefile faster. I discuss this procedure in a moment.

In any event, the returned values from the call to use the <TT><FONT FACE="Courier">ExtUtils::embed</FONT></TT>

function are used to define the link libraries and include files.

The returned values can be used directly in makefiles should the

Perl <TT><FONT FACE="Courier">-e</FONT></TT> command not work

or if you prefer to use a <TT><FONT FACE="Courier">make</FONT></TT>

variable.

<P>

Listing 26.1 presents a sample makefile for the Linux machine.

<HR>

<BLOCKQUOTE>

<B>Listing 26.1. A sample makefile.<BR>

</B>

</BLOCKQUOTE>

<BLOCKQUOTE>

<TT><FONT FACE="Courier">1 IncK= -D__USE_BSD_SIGNAL -Dbool=char

-DHAS_BOOL <BR>

<FONT FACE="ZAPFDINGBATS">&Acirc;</FONT>-I/usr/local/include&nbsp;&nbsp;-rdynamic&nbsp;&nbsp;-I

/usr/lib/perl5/i486-linux/5.002/CORE<BR>

2 LIBK =&nbsp;&nbsp;-L/usr/local/lib /usr/lib/perl5/i486-linux/5.002

<BR>

<FONT FACE="ZAPFDINGBATS">&Acirc;</FONT>/auto/DynaLoader/DynaLoader.a -L/usr/lib/perl5/i486-linux/5.002/CORE

<BR>

<FONT FACE="ZAPFDINGBATS">&Acirc;</FONT>-lperl -lgdbm -ldbm -ldb -ldl -lm -lc -lbsd<BR>

3 K_LIBS = -lgdbm -ldbm -ldb -ldl -lm -lc -lbsd<BR>

4 <BR>

5 ex2 : ex2.c<BR>

6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$(cc) -fno-strict-prototype ex2.c

-o ex2 -L$(LIBK) -I$(IncK)</FONT></TT>

</BLOCKQUOTE>

<HR>

<P>

Note the flags for the <TT><FONT FACE="Courier">gcc</FONT></TT>

compiler. The main problem with the <TT><FONT FACE="Courier">gcc</FONT></TT>

compiler is how the &quot;safefree&quot; function prototype is

declared in the <TT><FONT FACE="Courier">proto.h</FONT></TT> and

<TT><FONT FACE="Courier">handy.h</FONT></TT> files. There is a

slight difference in the syntax of each declaration, but programmatically

it makes no difference. To turn off the checking in <TT><FONT FACE="Courier">gcc</FONT></TT>,

simply use the <TT><FONT FACE="Courier">-fno-strict-prototype</FONT></TT>

flag at the command line for the <TT><FONT FACE="Courier">gcc</FONT></TT>

command.

<P>

The <TT><FONT FACE="Courier">LIBK</FONT></TT> and <TT><FONT FACE="Courier">IncK</FONT></TT>

paths are set to values that are derived from running the Perl

program shown in Listing 26.2. There is one possible problem you

must be aware of when you run this program: if you get errors

stating that it cannot find <TT><FONT FACE="Courier">embed.pm</FONT></TT>

in the <TT><FONT FACE="Courier">@Inc</FONT></TT> array, then modify

the <TT><FONT FACE="Courier">@Inc</FONT></TT> array to include

the path where the file is located. The commented lines in Listing

26.2 are examples.

<P>

If all else fails, copy the <TT><FONT FACE="Courier">embed.pm</FONT></TT>

path to the directory you happen to be in. If you get an error

stating that <TT><FONT FACE="Courier">embed.pm</FONT></TT> could

not be included or that it was empty, you have to modify the <TT><FONT FACE="Courier">embed.pm</FONT></TT>

file. Go to the statement with the <TT><FONT FACE="Courier">_END_</FONT></TT>

label and add the line <TT><FONT FACE="Courier">1;</FONT></TT>

before it. This step is only necessary if the <TT><FONT FACE="Courier">ExtUtils::embed</FONT></TT>

file could not be included.

<HR>

<BLOCKQUOTE>

<B>Listing 26.2. A sample makefile.<BR>

</B>

</BLOCKQUOTE>

<BLOCKQUOTE>

<TT><FONT FACE="Courier">&nbsp;1 #!/usr/bin/perl<BR>

&nbsp;2 <BR>

&nbsp;3 use ExtUtils::embed;<BR>

&nbsp;4 <BR>

&nbsp;5 #<BR>

&nbsp;6 # unshift(@Inc,&quot;/usr/local/lib/perl5/site_perl&quot;);

<BR>

&nbsp;7 #<BR>

&nbsp;8 <BR>

&nbsp;9 &amp;ccopts;&nbsp;&nbsp;# Create the path for headers

<BR>

10 &amp;ldopts;&nbsp;&nbsp;# Create the path for libraries</FONT></TT>

</BLOCKQUOTE>

<HR>

<P>

The call to the <TT><FONT FACE="Courier">&amp;ccopts</FONT></TT>

function creates the include path for use with the <TT><FONT FACE="Courier">-I</FONT></TT>

flag. The call to <TT><FONT FACE="Courier">&amp;ldopts</FONT></TT>

creates the path for libraries to be linked with the <TT><FONT FACE="Courier">-L</FONT></TT>

flag. Pipe the output to a saved file and create the makefile

as shown in Listing 26.1.

<H2><A NAME="AddingaPerlInterpreter"><B><FONT SIZE=5 COLOR=#FF0000>Adding

a Perl Interpreter to Your C Program</FONT></B></A></H2>

<P>

A C program using a Perl interpreter is really creating and running

a <TT><FONT FACE="Courier">PerlInterpreter</FONT></TT> object.

The <TT><FONT FACE="Courier">PerlInterpreter</FONT></TT> object

type is defined in the Perl library, and the C program simply

makes a reference to this library object. Several sample files

come in the <TT><FONT FACE="Courier">embed.pm</FONT></TT> file

and are used here as examples.

<P>

Listing 26.3 presents a quick example of how to embed a Perl interpreter

in a C program. 

<HR>

<BLOCKQUOTE>

<B>Listing 26.3. The first example from the </B><TT><B><FONT FACE="Courier">embed.pm</FONT></B></TT><B>

module.<BR>

</B>

</BLOCKQUOTE>

<BLOCKQUOTE>

<TT><FONT FACE="Courier">&nbsp;1 /*<BR>

&nbsp;2 ** Sample program used from embed.pm module package.<BR>

&nbsp;3 */<BR>

&nbsp;4 #include &lt;stdio.h&gt;<BR>

&nbsp;5 #include &lt;EXTERN.h&gt;<BR>

&nbsp;6 #include &lt;perl.h&gt;<BR>

&nbsp;7<BR>

&nbsp;8 static PerlInterpreter *my_perl;<BR>

&nbsp;9<BR>

10 main(int argc, char **argv, char **env)<BR>

11 {<BR>

12<BR>

13&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my_perl

= perl_alloc();<BR>

14&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perl_construct(my_perl);

<BR>

15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perl_parse(my_perl,

NULL, argc, argv, env);<BR>

16&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perl_run(my_perl);

<BR>

17&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perl_destruct(my_perl);

<BR>

18&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perl_free(my_perl);

<BR>

19 }</FONT></TT>

</BLOCKQUOTE>

<HR>

<P>

Lines 3 to 6 are the include headers you have to use to get this

to work. The <TT><FONT FACE="Courier">EXTERN.h</FONT></TT> and

<TT><FONT FACE="Courier">perl.h</FONT></TT> files will be picked

from where the Perl distribution is installed.

<P>

At line 8, the C program creates a pointer reference to the <TT><FONT FACE="Courier">PerlInterpreter</FONT></TT>

object defined in the Perl libraries. The reference will actually

be resolved in line 13 when the object is created.

<BLOCKQUOTE>

<TT><FONT FACE="Courier">At line 10, the main program interface

is called. All three arguments are required. Do not use either

of these lines because they both caused compiler error, even with

the -fno-strict-prototypes flag set:<BR>

main(int argc, char **argv);<BR>

main(int argc, char *argv[], char *env[])</FONT></TT>

</BLOCKQUOTE>

<P>

Lines 14 and 15 construct the <TT><FONT FACE="Courier">PerlInterpreter</FONT></TT>

object and parse any environment variables and command-line arguments.

You can read and execute Perl statements from a file at any time

in a C program by simply placing the name of the file in <TT><FONT FACE="Courier">argv[1]</FONT></TT>

before calling the <TT><FONT FACE="Courier">perl_run</FONT></TT>

function. The <TT><FONT FACE="Courier">perl_run </FONT></TT>function

is called at line 16 in the sample code in Listing 26.2. The function

can be called repeatedly in the C code before the calls are made

to destruct and free the object (lines 17 and 18 in the sample

code).

<P>

Now <TT><FONT FACE="Courier">make</FONT></TT> this program, called

<TT><FONT FACE="Courier">ex2.c</FONT></TT>, and run it. In the

sample run that follows, note how variables are defined and used

interactively in this sample run:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">$ <B>ex2<BR>

</B>$a = 1;<BR>

$b = 3;<BR>

print $a,&quot; &quot;,$b,&quot; &quot;,$a+$b,&quot;\n&quot;;

<BR>

^D<BR>

1 3 4<BR>

$</FONT></TT>

</BLOCKQUOTE>

<P>

To run a script file, simply redirect the contents of a file into

the input of the interpreter. The file you are feeding into your

C mini-interpreter does not have to have its execute bit set in

its permissions. Here's a sample run.

<BLOCKQUOTE>

<TT><FONT FACE="Courier">$<B> cat test.pl<BR>

</B>$a = 1;<BR>

$b = 1;<BR>

print &quot;a + b = &quot;, $a + $b, &quot;\n&quot;;<BR>

$<BR>

$ ex2 &lt; test.pl<BR>

a + b = 2<BR>

$</FONT></TT>

</BLOCKQUOTE>

<P>

There you have it-a small Perl interpreter embedded in C code.

Once you have this interpreter embedded in your C code, you can

evaluate Perl statements by simply feeding them into the interpreter

one line at a time.

<P>

There will be occasions, though, when you simply want to call

a Perl subroutine directly from within the C code. I show you

how to do this in the next section.

<H2><A NAME="CallingPerlSubroutinesfromWithin"><B><FONT SIZE=5 COLOR=#FF0000>Calling

Perl Subroutines from Within a C Program</FONT></B></A></H2>

<P>

In order to call a Perl subroutine by name, simply replace the

call to <TT><FONT FACE="Courier">perl_run()</FONT></TT> with a

call to <TT><FONT FACE="Courier">perl_call_argv()</FONT></TT>.

An example is shown in the code in Listing 26.4.

<HR>

<BLOCKQUOTE>

<B>Listing 26.4. Calling a subroutine in Perl directly.<BR>

</B>

</BLOCKQUOTE>

<BLOCKQUOTE>

<TT><FONT FACE="Courier">&nbsp;1 #include &lt;stdio.h&gt;<BR>

&nbsp;2 #include &lt;EXTERN.h&gt;<BR>

&nbsp;3 #include &lt;perl.h&gt;<BR>

&nbsp;4<BR>

&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;static PerlInterpreter *my_perl;

<BR>

&nbsp;6<BR>

&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int main(int argc, char **argv,

char **env)<BR>

&nbsp;8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<BR>

&nbsp;9&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;my_perl

= perl_alloc();<BR>

10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perl_construct(my_perl);

<BR>

11<BR>

12&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perl_parse(my_perl,

NULL, argc, argv, env);<BR>

13&nbsp;&nbsp;/* The next line calls a function in the file named

in<BR>

14&nbsp;&nbsp;&nbsp;* argv[1] of the program !!*/<BR>

15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perl_call_argv(&quot;showUser&quot;,

G_DISCARD | G_NOARGS, argv);<BR>

16&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perl_destruct(my_perl);

<BR>

17&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perl_free(my_perl);

<BR>

18&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</FONT></TT>

</BLOCKQUOTE>

<HR>

<P>

Look closely at line 15. This is really the only line that is

different from the code shown in Listing 26.3. A Perl subroutine

called <TT><FONT FACE="Courier">showUser</FONT></TT> is being

called here. The <TT><FONT FACE="Courier">showUser</FONT></TT>

subroutine takes no arguments, so you specify a <TT><FONT FACE="Courier">G_NOARGS</FONT></TT>

flag, and returns no values, so specify the <TT><FONT FACE="Courier">G_DISCARD</FONT></TT>

flag. The <TT><FONT FACE="Courier">argv</FONT></TT> vector is

used to store the filename in  <TT><FONT FACE="Courier">argv[1]</FONT></TT>.

To invoke this program, type the name of the file (<TT><FONT FACE="Courier">showMe.pl</FONT></TT>,

in this case) at the command line:

<BLOCKQUOTE>

<TT><FONT FACE="Courier">$ <B>ex3 showMe.pl<BR>

</B>Process 2689 : UID is 501 and GID is 501</FONT></TT>

</BLOCKQUOTE>

<P>

The <TT><FONT FACE="Courier">showMe.pl</FONT></TT> file named

in <TT><FONT FACE="Courier">argv[1]</FONT></TT> is shown in Listing

26.5.

<HR>

<BLOCKQUOTE>

<B>Listing 26.5. The file containing the subroutine being called.

<BR>

</B>

</BLOCKQUOTE>

<BLOCKQUOTE>

<TT><FONT FACE="Courier">1 #!/usr/bin/perl<BR>

2 sub showUser {<BR>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -