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

📄 ch12_15.htm

📁 By Tom Christiansen and Nathan Torkington ISBN 1-56592-243-3 First Edition, published August 1998
💻 HTM
字号:
<HTML><HEAD><TITLE>Recipe 12.14. Using h2ph to Translate C #include Files (Perl Cookbook)</TITLE><METANAME="DC.title"CONTENT="Perl Cookbook"><METANAME="DC.creator"CONTENT="Tom Christiansen &amp; Nathan Torkington"><METANAME="DC.publisher"CONTENT="O'Reilly &amp; Associates, Inc."><METANAME="DC.date"CONTENT="1999-07-02T01:41:57Z"><METANAME="DC.type"CONTENT="Text.Monograph"><METANAME="DC.format"CONTENT="text/html"SCHEME="MIME"><METANAME="DC.source"CONTENT="1-56592-243-3"SCHEME="ISBN"><METANAME="DC.language"CONTENT="en-US"><METANAME="generator"CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0"><LINKREV="made"HREF="mailto:online-books@oreilly.com"TITLE="Online Books Comments"><LINKREL="up"HREF="ch12_01.htm"TITLE="12. Packages, Libraries, and Modules"><LINKREL="prev"HREF="ch12_14.htm"TITLE="12.13. Referring to Packages Indirectly"><LINKREL="next"HREF="ch12_16.htm"TITLE="12.15. Using h2xs to Make a Module with C Code"></HEAD><BODYBGCOLOR="#FFFFFF"><img alt="Book Home" border="0" src="gifs/smbanner.gif" usemap="#banner-map" /><map name="banner-map"><area shape="rect" coords="1,-2,616,66" href="index.htm" alt="Perl Cookbook"><area shape="rect" coords="629,-11,726,25" href="jobjects/fsearch.htm" alt="Search this book" /></map><div class="navbar"><p><TABLEWIDTH="684"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch12_14.htm"TITLE="12.13. Referring to Packages Indirectly"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 12.13. Referring to Packages Indirectly"BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><B><FONTFACE="ARIEL,HELVETICA,HELV,SANSERIF"SIZE="-1"><ACLASS="chapter"REL="up"HREF="ch12_01.htm"TITLE="12. Packages, Libraries, and Modules"></A></FONT></B></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch12_16.htm"TITLE="12.15. Using h2xs to Make a Module with C Code"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 12.15. Using h2xs to Make a Module with C Code"BORDER="0"></A></TD></TR></TABLE></DIV><DIVCLASS="sect1"><H2CLASS="sect1"><ACLASS="title"NAME="ch12-25588">12.14. Using h2ph to Translate C #include Files</A></H2><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch12-pgfId-1344">Problem<ACLASS="indexterm"NAME="ch12-idx-1000005277-0"></A><ACLASS="indexterm"NAME="ch12-idx-1000005277-1"></A><ACLASS="indexterm"NAME="ch12-idx-1000005277-2"></A></A></H3><PCLASS="para">Someone gave you code that generates the bizarre error message:</P><PRECLASS="programlisting"><CODECLASS="userinput"><B><CODECLASS="replaceable"><I>Can't locate sys/syscall.ph in @INC (did you run h2ph?)</I></CODE></B></CODE><CODECLASS="userinput"><B><CODECLASS="replaceable"><I>(@INC contains: /usr/lib/perl5/i686-linux/5.00404 /usr/lib/perl5</I></CODE></B></CODE><CODECLASS="userinput"><B><CODECLASS="replaceable"><I>/usr/lib/perl5/site_perl/i686-linux /usr/lib/perl5/site_perl .)</I></CODE></B></CODE><CODECLASS="userinput"><B><CODECLASS="replaceable"><I>at some_program line 7.</I></CODE></B></CODE></PRE><PCLASS="para">You want to know what it means and how to fix it.</P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch12-pgfId-1360">Solution</A></H3><PCLASS="para">Get your system administrator to do this, running as the superuser:</P><PRECLASS="programlisting">% cd /usr/include; h2ph sys/syscall.h</PRE><PCLASS="para">However, most include files require other include files, which means you should probably just translate them all:</P><PRECLASS="programlisting">% cd /usr/include; h2ph *.h */*.h</PRE><PCLASS="para">If that reports too many filenames or misses some that are more deeply nested, try this instead:</P><PRECLASS="programlisting">% cd /usr/include; find . -name '*.h' -print | xargs h2ph</PRE></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch12-pgfId-1376">Discussion</A></H3><PCLASS="para">A file whose name ends in <CODECLASS="literal">&quot;.ph&quot;</CODE> has been created by the <EMCLASS="emphasis">h2ph</EM> tool, which translates C preprocessor directives from C <CODECLASS="literal">#include</CODE> files into Perl. The goal is to allow Perl code to access the same constants as C code. The <EMCLASS="emphasis">h2xs</EM> tool is a better approach in most cases because it provides compiled C code for your modules, not Perl code simulating C code. However, using <EMCLASS="emphasis">h2xs</EM> requires a lot more programming savvy (at least, for accessing C code) than <EMCLASS="emphasis">h2ph</EM> does.</P><PCLASS="para">When <EMCLASS="emphasis">h2ph</EM>'s translation process works, it's wonderful. When it doesn't, you're probably out of luck. As system architectures and include files become more complex, <EMCLASS="emphasis">h2ph</EM> fails more frequently. If you're lucky, the constants you need are already in the Fcntl, Socket, or POSIX modules. The POSIX module implements constants from <EMCLASS="emphasis">sys/file.h</EM>, <EMCLASS="emphasis">sys/errno.h</EM>, and <EMCLASS="emphasis">sys/wait.h</EM>, among others. It also allows fancy tty handling, as described in <ACLASS="xref"HREF="ch15_09.htm"TITLE="Using POSIX termios">Recipe 15.8</A>.</P><PCLASS="para">So what can you do with these .<EMCLASS="emphasis">ph</EM> files? Here are a few examples. The first uses the pessimally non-portable <CODECLASS="literal">syscall</CODE> function to access your operating system's <CODECLASS="literal">gettimeofday</CODE> system call. This implements the FineTime module described in <ACLASS="xref"HREF="ch12_12.htm"TITLE="Overriding Built-In Functions">Recipe 12.11</A>.</P><PRECLASS="programlisting"># file FineTime.pmpackage main;require 'sys/syscall.ph';die &quot;No SYS_gettimeofday in sys/syscall.ph&quot;    unless defined &amp;SYS_gettimeofday;package FineTime;    use strict;require Exporter;use vars qw(@ISA @EXPORT_OK);@ISA = qw(Exporter);@EXPORT_OK = qw(time);sub time() {    my $tv = pack(&quot;LL&quot;, ());  # presize buffer to two longs    syscall(&amp;main::SYS_gettimeofday, $tv, undef) &gt;= 0        or die &quot;gettimeofday: $!&quot;;    my($seconds, $microseconds) = unpack(&quot;LL&quot;, $tv);    return $seconds + ($microseconds / 1_000_000);}1;</PRE><PCLASS="para">If you are forced to <CODECLASS="literal">require</CODE> an old-style .<EMCLASS="emphasis">pl</EM> or .<EMCLASS="emphasis">ph</EM> file, do so from the main package (<CODECLASS="literal">package</CODE> <CODECLASS="literal">main</CODE> in the preceding code). These old libraries always put their symbols in the current package, and main serves as a reasonable rendezvous point. To use a symbol, use its fully qualified name, as we did with <CODECLASS="literal">main::SYS_gettimeofday</CODE>.</P><PCLASS="para">The <EMCLASS="emphasis">sys/ioctl.ph</EM> file, if you can get it to build on your system, is the gateway to your system's idiosyncratic I/O functions through the <ACLASS="indexterm"NAME="ch12-idx-1000006219-0"></A><CODECLASS="literal">ioctl</CODE> function. One such function is the TIOCSTI ioctl, shown in <ACLASS="xref"HREF="ch12_15.htm#ch12-25531"TITLE="jam">Example 12.1</A>. That abbreviation stands for "terminal I/O control, simulate terminal input." On systems that implement this function, it will push one character into your device stream so that the next time any process reads from that device, it gets the character you put there.</P><DIVCLASS="example"><H4CLASS="example"><ACLASS="title"NAME="ch12-25531">Example 12.1: jam</A></H4><PRECLASS="programlisting">#!/usr/bin/perl -w# <ACLASS="indexterm"NAME="ch12-idx-1000005347-0"></A>jam - stuff characters down STDIN's throatrequire 'sys/ioctl.ph';die &quot;no TIOCSTI&quot; unless defined &amp;TIOCSTI;sub jam {    local $SIG{TTOU} = &quot;IGNORE&quot;; # &quot;Stopped for tty output&quot;    local *TTY;  # make local filehandle    open(TTY, &quot;+&lt;/dev/tty&quot;)                 or die &quot;no tty: $!&quot;;    for (split(//, $_[0])) {        ioctl(TTY, &amp;TIOCSTI, $_)            or die &quot;bad TIOCSTI: $!&quot;;    }    close(TTY);}jam(&quot;@ARGV\n&quot;);</PRE></DIV><PCLASS="para">Since <EMCLASS="emphasis">sys/ioctl.h</EM> translation is so dodgy, you'll probably have to run this C program to get your TIOCSTI value.</P><PRECLASS="programlisting">% cat &gt; tio.c &lt;&lt;EOF &amp;&amp; cc tio.c &amp;&amp; a.out#include &lt;sys/ioctl.h&gt;main() { printf(&quot;%#08x\n&quot;, TIOCSTI); }EOF<CODECLASS="userinput"><B><CODECLASS="replaceable"><I>0x005412</I></CODE></B></CODE></PRE><PCLASS="para">Another popular use for <CODECLASS="literal">ioctl</CODE> is for figuring out your current <ACLASS="indexterm"NAME="ch12-idx-1000006222-0"></A>window size in rows and columns, and maybe even in pixels. This is shown in <ACLASS="xref"HREF="ch12_15.htm#ch12-29133"TITLE="winsz">Example 12.2</A>.</P><DIVCLASS="example"><H4CLASS="example"><ACLASS="title"NAME="ch12-29133">Example 12.2: winsz</A></H4><PRECLASS="programlisting">#!/usr/bin/perl# <ACLASS="indexterm"NAME="ch12-idx-1000005348-0"></A>winsz - find x and y for chars and pixelsrequire 'sys/ioctl.ph';die &quot;no TIOCGWINSZ &quot; unless defined &amp;TIOCGWINSZ;open(TTY, &quot;+&lt;/dev/tty&quot;)                     or die &quot;No tty: $!&quot;;unless (ioctl(TTY, &amp;TIOCGWINSZ, $winsize='')) {    die sprintf &quot;$0: ioctl TIOCGWINSZ (%08x: $!)\n&quot;, &amp;TIOCGWINSZ;}($row, $col, $xpixel, $ypixel) = unpack('S4', $winsize);print &quot;(row,col) = ($row,$col)&quot;;print &quot;  (xpixel,ypixel) = ($xpixel,$ypixel)&quot; if $xpixel || $ypixel;print &quot;\n&quot;;</PRE></DIV><PCLASS="para">As you see, as soon as you start playing with .<EMCLASS="emphasis">ph</EM> files, <CODECLASS="literal">unpack</CODE>ing binary data, and calling <CODECLASS="literal">syscall</CODE> and <CODECLASS="literal">ioctl</CODE>, you need to know about the C APIs that Perl normally hides. The only other thing that requires this much C knowledge is using the XS interface. Some suggest you should resist the temptation to descend into such unportable convolutions. Others feel that the demands put upon the trenchworkers are such that they must be forgiven these desperate measures.</P><PCLASS="para">Fortunately, less fragile mechanisms are increasingly available. CPAN modules for most of these functions now exist, which should theoretically prove more robust than sourcing .<EMCLASS="emphasis">ph</EM> files. <ACLASS="indexterm"NAME="ch12-idx-1000005279-0"></A><ACLASS="indexterm"NAME="ch12-idx-1000005279-1"></A><ACLASS="indexterm"NAME="ch12-idx-1000005279-2"></A></P></DIV><DIVCLASS="sect2"><H3CLASS="sect2"><ACLASS="title"NAME="ch12-pgfId-1508">See Also</A></H3><PCLASS="para"><ICLASS="filename">h2ph</I> (1); the instructions on running <ICLASS="filename">h2ph</I> in the <ICLASS="filename">INSTALL</I> file from the <ICLASS="filename">perl</I> source distribution; the <ACLASS="olink"HREF="../prog/ch03_164.htm"><CODECLASS="literal">syscall</CODE></A> and <ACLASS="olink"HREF="../prog/ch03_077.htm"><CODECLASS="literal">ioctl</CODE></A> functions in <ACLASS="olink"HREF="../prog/ch03_01.htm">Chapter 3</A> of <ACLASS="citetitle"HREF="../prog/index.htm"TITLE="Programming Perl"><CITECLASS="citetitle">Programming Perl</CITE></A> and in <ICLASS="filename">perlmod </I>(1); <ACLASS="xref"HREF="ch12_16.htm"TITLE="Using h2xs to Make a Module with C Code">Recipe 12.15</A></P></DIV></DIV><DIVCLASS="htmlnav"><P></P><HRALIGN="LEFT"WIDTH="684"TITLE="footer"><TABLEWIDTH="684"BORDER="0"CELLSPACING="0"CELLPADDING="0"><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch12_14.htm"TITLE="12.13. Referring to Packages Indirectly"><IMGSRC="../gifs/txtpreva.gif"ALT="Previous: 12.13. Referring to Packages Indirectly"BORDER="0"></A></TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><ACLASS="book"HREF="index.htm"TITLE="Perl Cookbook"><IMGSRC="../gifs/txthome.gif"ALT="Perl Cookbook"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228"><ACLASS="sect1"HREF="ch12_16.htm"TITLE="12.15. Using h2xs to Make a Module with C Code"><IMGSRC="../gifs/txtnexta.gif"ALT="Next: 12.15. Using h2xs to Make a Module with C Code"BORDER="0"></A></TD></TR><TR><TDALIGN="LEFT"VALIGN="TOP"WIDTH="228">12.13. Referring to Packages Indirectly</TD><TDALIGN="CENTER"VALIGN="TOP"WIDTH="228"><ACLASS="index"HREF="index/index.htm"TITLE="Book Index"><IMGSRC="../gifs/index.gif"ALT="Book Index"BORDER="0"></A></TD><TDALIGN="RIGHT"VALIGN="TOP"WIDTH="228">12.15. Using h2xs to Make a Module with C Code</TD></TR></TABLE><HRALIGN="LEFT"WIDTH="684"TITLE="footer"><FONTSIZE="-1"></DIV<!-- LIBRARY NAV BAR --> <img src="../gifs/smnavbar.gif" usemap="#library-map" border="0" alt="Library Navigation Links"><p> <a href="copyrght.htm">Copyright &copy; 2002</a> O'Reilly &amp; Associates. All rights reserved.</font> </p> <map name="library-map"> <area shape="rect" coords="1,0,85,94" href="../index.htm"><area shape="rect" coords="86,1,178,103" href="../lwp/index.htm"><area shape="rect" coords="180,0,265,103" href="../lperl/index.htm"><area shape="rect" coords="267,0,353,105" href="../perlnut/index.htm"><area shape="rect" coords="354,1,446,115" href="../prog/index.htm"><area shape="rect" coords="448,0,526,132" href="../tk/index.htm"><area shape="rect" coords="528,1,615,119" href="../cookbook/index.htm"><area shape="rect" coords="617,0,690,135" href="../pxml/index.htm"></map> </BODY></HTML>

⌨️ 快捷键说明

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