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

📄 ch21_04.htm

📁 编程珍珠,里面很多好用的代码,大家可以参考学习呵呵,
💻 HTM
📖 第 1 页 / 共 2 页
字号:
strings to the <tt class="literal">NULL</tt>-terminated <tt class="literal">args</tt> list passed to <tt class="literal">call_argv</tt>.For other data types, or to examine return values, you'll need tomanipulate the Perl stack.  That's touched on lightly later; for thedown and dirty, read the <em class="emphasis">perlcall</em> manpage bundled withPerl.</p><h3 class="sect2">21.4.4. Evaluating a Perl Statement from C</h3><p><a name="INDEX-3768"></a><a name="INDEX-3769"></a><a name="INDEX-3770"></a><a name="INDEX-3771"></a><a name="INDEX-3772"></a><a name="INDEX-3773"></a>Perl provides two functions for evaluating snippets of Perl code:<tt class="literal">eval_sv</tt> and <tt class="literal">eval_pv</tt>, described in the <em class="emphasis">perlapi</em>manpage.  Arguably, these are the only routines you'll ever needto execute Perl code from within your C program.  The code executedcan be as long as you wish, contain multiple statements, and employ<tt class="literal">use</tt>, <tt class="literal">require</tt>, or <tt class="literal">do</tt> to include other Perl files.</p><p><tt class="literal">eval_pv</tt> lets you evaluate individual Perl strings and thenextract variables for coercion into C types.  The following program,<em class="emphasis">string.c</em>, executes three Perl strings, extracting an <tt class="literal">int</tt> fromthe first, a <tt class="literal">float</tt> from the second, and a <tt class="literal">char *</tt> from the third:<blockquote><pre class="programlisting">#include &lt;EXTERN.h&gt;#include &lt;perl.h&gt;static PerlInterpreter *my_perl;main (int argc, char **argv, char **env){   STRLEN n_a;   char *embedding[] = { "", "-e", "0" };   my_perl = perl_alloc();   perl_construct( my_perl );   perl_parse(my_perl, NULL, 3, embedding, NULL);   perl_run(my_perl);   /** Treat $a as an integer **/   eval_pv("$a = 3; $a **= 2", TRUE);   printf("a = %d\n", SvIV(get_sv("a", FALSE)));   /** Treat $a as a float **/   eval_pv("$a = 3.14; $a **= 2", TRUE);   printf("a = %f\n", SvNV(get_sv("a", FALSE)));   /** Treat $a as a string **/   eval_pv("$a = 'relreP kcaH rehtonA tsuJ'; $a = reverse($a);", TRUE);   printf("a = %s\n", SvPV(get_sv("a", FALSE), n_a));   perl_destruct(my_perl);   perl_free(my_perl);}</pre></blockquote></p><p><a name="INDEX-3774"></a>All of the functions with <tt class="literal">Sv</tt> in their names convert Perl scalars toC types.  They're described in the <em class="emphasis">perlguts</em> and <em class="emphasis">perlapi</em> manpages.  Ifyou compile and run this program, you'll see the results of using<tt class="literal">SvIV</tt> to create an <tt class="literal">int</tt>, <tt class="literal">SvNV</tt> to create a <tt class="literal">float</tt>, and<tt class="literal">SvPV</tt> to create a C string:<blockquote><pre class="programlisting">a = 9a = 9.859600a = Just Another Hack Perler</pre></blockquote>In the previous example, we've created a global variable to temporarilystore the computed value of our evaluated expression.  It is alsopossible (and in most cases better form) to use the return valueof <tt class="literal">eval_pv</tt> instead of throwing it away:<blockquote><pre class="programlisting">SV *val = eval_pv("reverse 'relreP kcaH rehtonA tsuJ'", TRUE);printf("%s\n", SvPV(val,n_a));</pre></blockquote><a name="INDEX-3775"></a>The <em class="emphasis">perlembed</em> manpage bundled with Perl includesa demonstration of <tt class="literal">eval_sv</tt> that lets you make use ofPerl's regular expression capabilities from your C program.</p><h3 class="sect2">21.4.5. Fiddling with the Perl Stack from C</h3><p><a name="INDEX-3776"></a><a name="INDEX-3777"></a><a name="INDEX-3778"></a><a name="INDEX-3779"></a>When trying to explain stacks, most computer sciencetextbooks<a href="#FOOTNOTE-2">[2]</a> mumblesomething about spring-loaded columns of cafeteria plates: the lastthing you pushed on the stack is the first thing you pop off.  That'lldo for our purposes: your C program will push some arguments onto "thePerl stack", shut its eyes while some magic happens, and then pop theresults--the return value of your Perl subroutine--off the stack.</p><blockquote class="footnote"><a name="FOOTNOTE-2"></a><p>[2] Plus the occasional Perl book.</p></blockquote><p><a name="INDEX-3780"></a><a name="INDEX-3781"></a><a name="INDEX-3782"></a>We'll present an example here without much explanation.  To reallyunderstand what's going on, you'll need to know how to convert betweenC types and Perl types, with <tt class="literal">newSViv</tt> and <tt class="literal">sv_setnv</tt> and <tt class="literal">newAV</tt>and all their friends described in the <em class="emphasis">perlguts</em> and <em class="emphasis">perlapi</em>manpages.  Then you'll need to read <em class="emphasis">perlcall</em> to learn how tomanipulate the Perl stack.</p><p><a name="INDEX-3783"></a><a name="INDEX-3784"></a>Because C has no built-in function for integer exponentiation, let'smake Perl's <tt class="literal">**</tt> operator available to it.  (This is less useful thanit sounds, since Perl implements <tt class="literal">**</tt> with C's <em class="emphasis">pow</em>(3) function.)First we'll create an exponentiation function in a library file called<em class="emphasis">power.pl</em>:<blockquote><pre class="programlisting">sub expo {    my ($a, $b) = @_;    return $a ** $b;}</pre></blockquote>Now we'll create a C program, <em class="emphasis">power.c</em>, with a function called<tt class="literal">PerlPower</tt> that pushes the two arguments onto the stack, invokes<tt class="literal">expo</tt>, and pops the return value out:<blockquote><pre class="programlisting">#include &lt;EXTERN.h&gt;#include &lt;perl.h&gt;static PerlInterpreter *my_perl;/* "Real programmers can write assembly code in any language." */static voidPerlPower(int a, int b){  dSP;                            /* initialize stack pointer         */  ENTER;                          /* everything created after here    */  SAVETMPS;                       /* ...is a temporary variable.      */  PUSHMARK(SP);                   /* remember the stack pointer       */  XPUSHs(sv_2mortal(newSViv(a))); /* push the base onto the stack     */  XPUSHs(sv_2mortal(newSViv(b))); /* push the exponent onto stack     */  PUTBACK;                        /* make local stack pointer global  */  call_pv("expo", G_SCALAR);      /* call the function                */  SPAGAIN;                        /* refresh stack pointer            */                                  /* pop the return value from stack  */  printf ("%d to the %dth power is %d.\n", a, b, POPi);  PUTBACK;  FREETMPS;                       /* free that return value           */  LEAVE;                          /* ...and the XPUSHed "mortal" args */}int main (int argc, char **argv, char **env){  char *my_argv[] = { "", "power.pl" };  my_perl = perl_alloc();  perl_construct( my_perl );  perl_parse(my_perl, NULL, 2, my_argv, (char **)NULL);  perl_run(my_perl);  PerlPower(3, 4);                      /*** Compute 3 ** 4 ***/  perl_destruct(my_perl);  perl_free(my_perl);}</pre></blockquote>You can compile <em class="emphasis">power.c</em> into <em class="emphasis">power</em> like so:<blockquote><pre class="programlisting">% <tt class="userinput"><b>cc -o power power.c `perl -MExtUtils::Embed -e ccopts -e ldopts`</b></tt>% <tt class="userinput"><b>power</b></tt>3 to the 4th power is 81.</pre></blockquote>Now your <em class="emphasis">power</em> program can sit around being different too.</p><!-- BOTTOM NAV BAR --><hr width="515" align="left"><div class="navbar"><table width="515" border="0"><tr><td align="left" valign="top" width="172"><a href="ch21_03.htm"><img src="../gifs/txtpreva.gif" alt="Previous" border="0"></a></td><td align="center" valign="top" width="171"><a href="index.htm"><img src="../gifs/txthome.gif" alt="Home" border="0"></a></td><td align="right" valign="top" width="172"><a href="ch21_05.htm"><img src="../gifs/txtnexta.gif" alt="Next" border="0"></a></td></tr><tr><td align="left" valign="top" width="172">21.3. Extending Perl (Using C from Perl)</td><td align="center" valign="top" width="171"><a href="index/index.htm"><img src="../gifs/index.gif" alt="Book Index" border="0"></a></td><td align="right" valign="top" width="172">21.5. The Moral of the Story</td></tr></table></div><hr width="515" align="left"><!-- LIBRARY NAV BAR --><img src="../gifs/smnavbar.gif" usemap="#library-map" border="0" alt="Library Navigation Links"><p><font size="-1"><a href="copyrght.htm">Copyright &copy; 2001</a> O'Reilly &amp; Associates. All rights reserved.</font></p><map name="library-map"> <area shape="rect" coords="2,-1,79,99" href="../index.htm"><area shape="rect" coords="84,1,157,108" href="../perlnut/index.htm"><area shape="rect" coords="162,2,248,125" href="../prog/index.htm"><area shape="rect" coords="253,2,326,130" href="../advprog/index.htm"><area shape="rect" coords="332,1,407,112" href="../cookbook/index.htm"><area shape="rect" coords="414,2,523,103" href="../sysadmin/index.htm"></map><!-- END OF BODY --></body></html>

⌨️ 快捷键说明

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