By Tom Christiansen and Nathan Torkington ISBN 1-56592-243-3 First Edition, published August 1998

源代码在线查看: ch12_15.htm

软件大小: 1747 K
上传用户: tiandl
关键词: Christiansen Torkington published Edition
下载地址: 免注册下载 普通下载 VIP

相关代码

								>				>				Recipe 12.14. Using h2ph to Translate C #include Files (Perl Cookbook)								NAME="DC.title"				CONTENT="Perl Cookbook">				NAME="DC.creator"				CONTENT="Tom Christiansen & Nathan Torkington">				NAME="DC.publisher"				CONTENT="O'Reilly & Associates, Inc.">				NAME="DC.date"				CONTENT="1999-07-02T01:41:57Z">				NAME="DC.type"				CONTENT="Text.Monograph">				NAME="DC.format"				CONTENT="text/html"				SCHEME="MIME">				NAME="DC.source"				CONTENT="1-56592-243-3"				SCHEME="ISBN">				NAME="DC.language"				CONTENT="en-US">				NAME="generator"				CONTENT="Jade 1.1/O'Reilly DocBook 3.0 to HTML 4.0">				REV="made"				HREF="mailto:online-books@oreilly.com"				TITLE="Online Books Comments">				REL="up"				HREF="ch12_01.htm"				TITLE="12. Packages, Libraries, and Modules">				REL="prev"				HREF="ch12_14.htm"				TITLE="12.13. Referring to Packages Indirectly">				REL="next"				HREF="ch12_16.htm"				TITLE="12.15. Using h2xs to Make a Module with C Code">				>				BGCOLOR="#FFFFFF">								WIDTH="684"				BORDER="0"				CELLSPACING="0"				CELLPADDING="0"				>				>				ALIGN="LEFT"				VALIGN="TOP"				WIDTH="228"				>				CLASS="sect1"				HREF="ch12_14.htm"				TITLE="12.13. Referring to Packages Indirectly"				>				SRC="../gifs/txtpreva.gif"				ALT="Previous: 12.13. Referring to Packages Indirectly"				BORDER="0">				>				>				ALIGN="CENTER"				VALIGN="TOP"				WIDTH="228"				>				>				FACE="ARIEL,HELVETICA,HELV,SANSERIF"				SIZE="-1"				>				CLASS="chapter"				REL="up"				HREF="ch12_01.htm"				TITLE="12. Packages, Libraries, and Modules"				>				>				>				>				>				ALIGN="RIGHT"				VALIGN="TOP"				WIDTH="228"				>				CLASS="sect1"				HREF="ch12_16.htm"				TITLE="12.15. Using h2xs to Make a Module with C Code"				>				SRC="../gifs/txtnexta.gif"				ALT="Next: 12.15. Using h2xs to Make a Module with C Code"				BORDER="0">				>				>				>				>				>				CLASS="sect1"				>				CLASS="sect1"				>				CLASS="title"				NAME="ch12-25588"				>12.14. Using h2ph to Translate C #include Files				>				>				CLASS="sect2"				>				CLASS="sect2"				>				CLASS="title"				NAME="ch12-pgfId-1344"				>Problem				CLASS="indexterm"				NAME="ch12-idx-1000005277-0"				>				>				CLASS="indexterm"				NAME="ch12-idx-1000005277-1"				>				>				CLASS="indexterm"				NAME="ch12-idx-1000005277-2"				>				>				>				>				CLASS="para"				>Someone gave you code that generates the bizarre error message:				>				CLASS="programlisting"				>				CLASS="userinput"				>				>				CLASS="replaceable"				>				>Can't locate sys/syscall.ph in @INC (did you run h2ph?)				>				>				>				>								CLASS="userinput"				>				>				CLASS="replaceable"				>				>(@INC contains: /usr/lib/perl5/i686-linux/5.00404 /usr/lib/perl5				>				>				>				>								CLASS="userinput"				>				>				CLASS="replaceable"				>				>/usr/lib/perl5/site_perl/i686-linux /usr/lib/perl5/site_perl .)				>				>				>				>								CLASS="userinput"				>				>				CLASS="replaceable"				>				>at some_program line 7.				>				>				>				>				>				CLASS="para"				>You want to know what it means and how to fix it.				>				>				CLASS="sect2"				>				CLASS="sect2"				>				CLASS="title"				NAME="ch12-pgfId-1360"				>Solution				>				>				CLASS="para"				>Get your system administrator to do this, running as the superuser:				>				CLASS="programlisting"				>% cd /usr/include; h2ph sys/syscall.h				>				CLASS="para"				>However, most include files require other include files, which means you should probably just translate them all:				>				CLASS="programlisting"				>% cd /usr/include; h2ph *.h */*.h				>				CLASS="para"				>If that reports too many filenames or misses some that are more deeply nested, try this instead:				>				CLASS="programlisting"				>% cd /usr/include; find . -name '*.h' -print | xargs h2ph				>				>				CLASS="sect2"				>				CLASS="sect2"				>				CLASS="title"				NAME="ch12-pgfId-1376"				>Discussion				>				>				CLASS="para"				>A file whose name ends in 				CLASS="literal"				>".ph"				> has been created by the 				CLASS="emphasis"				>h2ph				> tool, which translates C preprocessor directives from C 				CLASS="literal"				>#include				> files into Perl. The goal is to allow Perl code to access the same constants as C code. The 				CLASS="emphasis"				>h2xs				> 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 				CLASS="emphasis"				>h2xs				> requires a lot more programming savvy (at least, for accessing C code) than 				CLASS="emphasis"				>h2ph				> does.				>				CLASS="para"				>When 				CLASS="emphasis"				>h2ph				>'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, 				CLASS="emphasis"				>h2ph				> 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 				CLASS="emphasis"				>sys/file.h				>, 				CLASS="emphasis"				>sys/errno.h				>, and 				CLASS="emphasis"				>sys/wait.h				>, among others. It also allows fancy tty handling, as described in 				CLASS="xref"				HREF="ch15_09.htm"				TITLE="Using POSIX termios"				>Recipe 15.8				>.				>				CLASS="para"				>So what can you do with these .				CLASS="emphasis"				>ph				> files? Here are a few examples. The first uses the pessimally non-portable 				CLASS="literal"				>syscall				> function to access your operating system's 				CLASS="literal"				>gettimeofday				> system call. This implements the FineTime module described in 				CLASS="xref"				HREF="ch12_12.htm"				TITLE="Overriding Built-In Functions"				>Recipe 12.11				>.				>				CLASS="programlisting"				># file FineTime.pm				package main;				require 'sys/syscall.ph';				die "No SYS_gettimeofday in sys/syscall.ph"				    unless defined &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("LL", ());  # presize buffer to two longs				    syscall(&main::SYS_gettimeofday, $tv, undef) >= 0				        or die "gettimeofday: $!";				    my($seconds, $microseconds) = unpack("LL", $tv);				    return $seconds + ($microseconds / 1_000_000);				}								1;				>				CLASS="para"				>If you are forced to 				CLASS="literal"				>require				> an old-style .				CLASS="emphasis"				>pl				> or .				CLASS="emphasis"				>ph				> file, do so from the main package (				CLASS="literal"				>package				> 				CLASS="literal"				>main				> 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 				CLASS="literal"				>main::SYS_gettimeofday				>.				>				CLASS="para"				>The 				CLASS="emphasis"				>sys/ioctl.ph				> file, if you can get it to build on your system, is the gateway to your system's idiosyncratic I/O functions through the 				CLASS="indexterm"				NAME="ch12-idx-1000006219-0"				>				>				CLASS="literal"				>ioctl				> function. One such function is the TIOCSTI ioctl, shown in 				CLASS="xref"				HREF="ch12_15.htm#ch12-25531"				TITLE="jam"				>Example 12.1				>. 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.				>				CLASS="example"				>				CLASS="example"				>				CLASS="title"				NAME="ch12-25531"				>Example 12.1: jam				>				>				CLASS="programlisting"				>#!/usr/bin/perl -w				# 				CLASS="indexterm"				NAME="ch12-idx-1000005347-0"				>				>jam - stuff characters down STDIN's throat				require 'sys/ioctl.ph';				die "no TIOCSTI" unless defined &TIOCSTI;				sub jam {				    local $SIG{TTOU} = "IGNORE"; # "Stopped for tty output"				    local *TTY;  # make local filehandle				    open(TTY, "+</dev/tty")                 or die "no tty: $!";				    for (split(//, $_[0])) {				        ioctl(TTY, &TIOCSTI, $_)            or die "bad TIOCSTI: $!";				    }				    close(TTY);				}				jam("@ARGV\n");				>				>				CLASS="para"				>Since 				CLASS="emphasis"				>sys/ioctl.h				> translation is so dodgy, you'll probably have to run this C program to get your TIOCSTI value.				>				CLASS="programlisting"				>% cat > tio.c <<EOF && cc tio.c && a.out				#include <sys/ioctl.h>				main() { printf("%#08x\n", TIOCSTI); }				EOF								CLASS="userinput"				>				>				CLASS="replaceable"				>				>0x005412				>				>				>				>				>				CLASS="para"				>Another popular use for 				CLASS="literal"				>ioctl				> is for figuring out your current 				CLASS="indexterm"				NAME="ch12-idx-1000006222-0"				>				>window size in rows and columns, and maybe even in pixels. This is shown in 				CLASS="xref"				HREF="ch12_15.htm#ch12-29133"				TITLE="winsz"				>Example 12.2				>.				>				CLASS="example"				>				CLASS="example"				>				CLASS="title"				NAME="ch12-29133"				>Example 12.2: winsz				>				>				CLASS="programlisting"				>#!/usr/bin/perl				# 				CLASS="indexterm"				NAME="ch12-idx-1000005348-0"				>				>winsz - find x and y for chars and pixels				require 'sys/ioctl.ph';				die "no TIOCGWINSZ " unless defined &TIOCGWINSZ;				open(TTY, "+</dev/tty")                     or die "No tty: $!";				unless (ioctl(TTY, &TIOCGWINSZ, $winsize='')) {				    die sprintf "$0: ioctl TIOCGWINSZ (%08x: $!)\n", &TIOCGWINSZ;				}				($row, $col, $xpixel, $ypixel) = unpack('S4', $winsize);				print "(row,col) = ($row,$col)";				print "  (xpixel,ypixel) = ($xpixel,$ypixel)" if $xpixel || $ypixel;				print "\n";				>				>				CLASS="para"				>As you see, as soon as you start playing with .				CLASS="emphasis"				>ph				> files, 				CLASS="literal"				>unpack				>ing binary data, and calling 				CLASS="literal"				>syscall				> and 				CLASS="literal"				>ioctl				>, 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.				>				CLASS="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 .				CLASS="emphasis"				>ph				> files. 				CLASS="indexterm"				NAME="ch12-idx-1000005279-0"				>				>				CLASS="indexterm"				NAME="ch12-idx-1000005279-1"				>				>				CLASS="indexterm"				NAME="ch12-idx-1000005279-2"				>				>				>				>				CLASS="sect2"				>				CLASS="sect2"				>				CLASS="title"				NAME="ch12-pgfId-1508"				>See Also				>				>				CLASS="para"				>				CLASS="filename"				>h2ph				> (1); the instructions on running 				CLASS="filename"				>h2ph				> in the 				CLASS="filename"				>INSTALL				> file from the 				CLASS="filename"				>perl				> source distribution; the 				CLASS="olink"				HREF="../prog/ch03_164.htm"				>				CLASS="literal"				>syscall				>				> and 				CLASS="olink"				HREF="../prog/ch03_077.htm"				>				CLASS="literal"				>ioctl				>				> functions in 				CLASS="olink"				HREF="../prog/ch03_01.htm"				>Chapter 3				> of 				CLASS="citetitle"				HREF="../prog/index.htm"				TITLE="Programming Perl"				>				CLASS="citetitle"				>Programming Perl				>				> and in 				CLASS="filename"				>perlmod 				>(1); 				CLASS="xref"				HREF="ch12_16.htm"				TITLE="Using h2xs to Make a Module with C Code"				>Recipe 12.15				>				>				>				>				CLASS="htmlnav"				>				>				>				ALIGN="LEFT"				WIDTH="684"				TITLE="footer">				WIDTH="684"				BORDER="0"				CELLSPACING="0"				CELLPADDING="0"				>				>				ALIGN="LEFT"				VALIGN="TOP"				WIDTH="228"				>				CLASS="sect1"				HREF="ch12_14.htm"				TITLE="12.13. Referring to Packages Indirectly"				>				SRC="../gifs/txtpreva.gif"				ALT="Previous: 12.13. Referring to Packages Indirectly"				BORDER="0">				>				>				ALIGN="CENTER"				VALIGN="TOP"				WIDTH="228"				>				CLASS="book"				HREF="index.htm"				TITLE="Perl Cookbook"				>				SRC="../gifs/txthome.gif"				ALT="Perl Cookbook"				BORDER="0">				>				>				ALIGN="RIGHT"				VALIGN="TOP"				WIDTH="228"				>				CLASS="sect1"				HREF="ch12_16.htm"				TITLE="12.15. Using h2xs to Make a Module with C Code"				>				SRC="../gifs/txtnexta.gif"				ALT="Next: 12.15. Using h2xs to Make a Module with C Code"				BORDER="0">				>				>				>				>				ALIGN="LEFT"				VALIGN="TOP"				WIDTH="228"				>12.13. Referring to Packages Indirectly				>				ALIGN="CENTER"				VALIGN="TOP"				WIDTH="228"				>				CLASS="index"				HREF="index/index.htm"				TITLE="Book Index"				>				SRC="../gifs/index.gif"				ALT="Book Index"				BORDER="0">				>				>				ALIGN="RIGHT"				VALIGN="TOP"				WIDTH="228"				>12.15. Using h2xs to Make a Module with C Code				>				>				>				ALIGN="LEFT"				WIDTH="684"				TITLE="footer">				SIZE="-1"				>				>				>							

相关资源