Анимация
JavaScript
|
Главная Библионтека % cd /usr/lnclude; h2ph sys/syscall.h Однако многие заголовочные файлы включают другие заголовочные файлы; иными словами, придется преобразовать йк все: % cd /usr/lnclude; h2ph -.h •/*.h Если вы получите сообщение о слишком большом количестве файлов или если некоторые файлы в подкаталогах не будут найдены, попробуйте другую команду: % cd /usr/include; find . -папе .h -print xargs h2ph Комментарий Файлы с расширением .ph создаются утилитой h2ph, которая преобразует директивы препроцессора С из #1пс1ис1е-файлов в Perl. Это делается для того, чтобы программа на Perl могла работать с теми же константами, что и программа на С. Утилита h2xs обычно оказывается более удачным решением, поскольку вместо кода Perl, имитирующего код С, она предоставляет откомпилированный код С. Однако работа с h2xs требует намного большего опыта программирования (по крайней мере, в том, что касается С), чем h2ph. Если процесс преобразования Н2рк работает, все прекрасно. Если нет - что ж, вам не повезло. Усложнение системных архитектур и заголовочных файлов приводит к более частым отказам h2ph. Если повезет, необходимые константы уже будут присутствовать в модулях Fcntl, Socket или POSIX. В частности, модуль POSIX реализует константы из sys/file.h, sys/ermo.h и sys/wait.h. Кроме того, он обеспечивает выполнение нестандартных операций с терминалом (см. рецепт 15.8). Так что же можно сделать с файлом .ph? Рассмотрим несколько примеров. В первом примере непереносимая функция syscall используется для вызова системной функции gettimeofday. Перед вами реализация модуля FineTime, описанного в рецепте 12.11. # Файл FineTime.рт 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 timeO { my Stv = pack("LL", ()); # presize buffer to two longs syscall(&main::SYS gettimeofday, Stv, undef) >= 0 or die "gettimeofday; $!"; 12.14. Применение h2ph для преобразования заголовочных файлов С 435 myCSseconds, Smicroseconds) = unpackCLL", $tv); return Sseconds + (Smicroseconds / 1 000 000); > Если вам приходится вызывать require для старых файлов .р1 или .ph, сделайте это из главного пакета (package main в приведенном выше коде). Эти старые библиотеки всегда помещают свои символические имена в текущий пакет, а main служит «местом встречи». Чтобы использовать имя, уточните его, как мы поступили с main:: SYS gettimeofday. Файл sys/ioctl.ph, если вам удастся построить его в своей системе, открывает доступ к функциям ввода/вывода вашей системы через функции ioctl. К их числу принадлежит функция TIOCSTI из примера 12.1. Сокращение TIOCSTI означает «управление терминальным вводом/выводом, имитация терминального ввода» (terminal I/O control, simulate terminal input). В системах, где эта функция реализована, она вставляет один символ в поток устройства, чтобы при следующем чтении из устройства со стороны любого процесса был получен вставленный символ. Пример 12.1. jam #!/usr/bin/perl -w # jam - вставка символов в STDIN require sys/ioctl.ph; die "no TIOCSTI" unless defined mOCSTI; sub jam { local SSIG{TTOU} = "IGNORE"; # "Остановка для вывода на терминал" local TTY; п Создать локальный манипулятор open(TTY, "+</dev/tty") or die "no tty; $i"; for (split( , $ [0])) { ioctKTTY, &TI0CSTI, $ ) or die "bad TIOCSTI; S!"; close(TTY); jam("@ARGV\n"); Поскольку преобразование sys/ioctl.h может вызвать некоторые сложности, вероятно, для получения кода TIOCSTI вам придется запустить следующую программу на С: % cat > tio.c «EOF && со tio.c && а.out #include <sys/ioctl.h> mainO { printf("%#08x\n", TIOCSTI); } 0x005412 Функция ioctl также часто применяется для определения размеров текущего окна в строках/столбцах и даже в пикселях. Исходный текст программы приведен в примере 12.2. 436 Глава 12 • Пакеты, библиотеки и модули Пример 12.2. winsz #! /usr/bin/perl # winsz - определение размеров окна в символах и пикселях require sys/ioctl.ph; die "no TIOCGWINSZ " unless defined &TIOCGWINSZ; open(TTY, "+</dev/tty") or die "No tty: $!"; unless (loctKTTY, &TIOCGWINSZ, $winsize=)) { die sprintf "$0: ioctl TIOCGWINSZ (%08x: $i)\n", &TI0CGWINSZ; ($row, Scol, Sxpixel, Sypixel) = unpackCS4, Swinsize); print (row,col) = ($row,Scol)"; print " (xpixel,ypixel) = (Sxpixel,Sypixel)" if Sxpixel Sypixel; print "\n", Как видите, для экспериментов с файлами .ph, распаковкой двоичных данных и вызовами syscall и ioctl необходимо хорошо знать прикладной интерфейс С, обычно скрьшаемый Perl. Единственное, что требует такого же уровня знаний С - это интерфейс XS. Одни считают, что программисты должны бороться с искушением и за версту обходить подобные непереносимые решения. По мнению других, жесткие требования, поставленные перед рядовым программистом, оправдывают самые отчаянные меры. К счастью, все большее распространение получают менее хрупкие механизмы. Для большинства этих функций появились модули CPAN. Теоретически они работают надежнее, чем обращения к файлам .ph. Х> Смотри также- Описание функций syscall и ioctl вperlmod{i); инструкции по работе с h2ph в файле INSTALL исходной поставки Perl; h2ph{\); рецепт 12.15. 12.15. Применение h2xs для создания модулей с кодом С Проблема Вам хотелось бы работать с функциями С из Perl. Решение Воспользуйтесь утилитой h2xs для построения необходимых файлов шаблонов, заполните их соответствующим образом и введите: % perl Makefile. PL % make Комментарий При написании модуля Perl необязательно ограничиваться одним Perl. Как и для любого другого модуля, выберите имя и вызовите для него утилиту h2xs. Мы со- 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 [ 139 ] 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 |