Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: разработка для Web > Включение в PERL кода на C


Автор: Rigel 5.8.2008, 15:46
Задача у меня такая: поисковый механизм роется сначала в базе а потом, как окончательный поиск, в файлах (этот, окончательный, модуль, который должен пересмотреть несколько тысяч файлов, написан на С). Написан предварительный механизм, который передает данные из Перла в EXE-файл:
Код

my $ResultString = `../XPortal/pages/file21.exe $inString`;

В таком виде все работает: формируется строка с параметрами, которые потом, в С, вытаскиваются из argv[], переводятся в char и используются по назначению. На выходе результаты поиска через разделитель добавляются в string и сплитятся потом в perl по этому самому разделителю. Но вот в чем проблема: и входных и выходных данных много, может быть и мегабайты, то есть, командная строка не подходит. Я пытаюсь воспользоваться STDIN и STDOUT, но что-то у меня не получается: если вывод в С я примерно могу себе представить:
Код

my $SearchDatPath = "|../XPortal/pages/file21.exe";
open(SEARCHDAT, $SearchDatPath);
print SEARCHDAT "$inString\n";
close SEARCHDAT;

То чтение из входного потока хоть тут тресни не работает, хотя я С в этот потомк пишу вполне членораздельную статику:
Код

read STDIN, $ResultString, $ENV{CONTENT_LENGTH}; 

Что-то в этом роде не получается. Помогите, пожалуйста, с вводом и выводом. 

Автор: ginnie 5.8.2008, 16:43
Уважаемый Rigel, рекомендую почитать http://perldoc.perl.org/perlipc.html#Bidirectional-Communication-with-Another-Process.

Автор: Rigel 5.8.2008, 16:55
Это я знаю, но я не хочу запускать независимый процесс - для моих целей это явное излишество. Мне нужно запустить программу, дождаться ее завершения и прочитать то, что она вывела в стандартный поток, не больше. Если бы не обилие параметров, вполне подошла бы командная строка.

Автор: ginnie 5.8.2008, 18:42
Уважаемый Rigel, я не понял Вашу фразу
Цитата

но я не хочу запускать независимый процесс - для моих целей это явное излишество

не могли бы Вы ее пояснить?

Автор: Rigel 6.8.2008, 08:22
Очень просто - мне нужно, чтобы программа на Си прошлась бы по файлам библиотеки в поисках ключевых слов. Файлы выбираются по другим признакам, отсюда громадный массив на входе. Если поисковик идет по ВСЕМ файлам, то работает такое его включение:
Код

my $ResultString = `../XPortal/pages/file21.exe $inString`;

но командная строка не может выдержать еще и имена файлов, кроме поисковых байтов. Я сейчас продумываю кеширующую схему - когда процессу передается имя сессионного файла, содержащего потребные данные, и в этот же файл Си пишет свой результат. Но, возможно, есть более простая схема, как я писал в первом письме, когда данные другой программе передаются через стандартный поток ввода, программа на Си пишет в стандартный поток вывода а Перл этот поток читает (и все это еще и с mod_perl работает).

Автор: ginnie 6.8.2008, 11:14
Уважаемый Rigel, если Вас устраивает

Код

my $ResultString = `../XPortal/pages/file21.exe $inString`;


почему не подходит Bidirectional Communication with Another Process? В первом и во втором случае запускается внешний процесс.

Автор: shamber 6.8.2008, 13:27
Уважаемый Rigel, 
вот и мне так кажется. Только Bidirectional Communication даст вам больше свободы действий

Автор: Rigel 6.8.2008, 20:05
Увы, не нужна не свобода а кроссплатформенность...

Автор: korob2001 7.8.2008, 16:59
Цитата(Rigel @  6.8.2008,  17:05 Найти цитируемый пост)
Увы, не нужна не свобода а кроссплатформенность... 

В этом случае придётся вообще отказаться от C и переписать всё на Perl.  Так же можно посмотреть в сторону модулей Inline::... . Вот http://forum.vingrad.ru/forum/topic-124314/hl/inline/index.html# я приводил пример того, как можно втсроить встроить Java код, в программу Perl, после чего Perl воспринимает методы Java класса, как свои собственные. В данном случае речь шла о модуле Inline::Java, в нашем же случае следует обратьтиться к модулю Inline::C или Inline::CPP.

Автор: Rigel 8.8.2008, 08:38
Спасибо, это уже ближе - но не совсем то: мне нужен не код С а его скорость  smile  . Сначала я написал код на PERL, естественно - он обрабатывал 200 файлов за 37 секунд. Написанный на C он проходит те же 200 файлов меньше чем за секунду - точнее не смог измерить. По техзаданию, поисковка должна обслуживать сто тысяч файлов - поэтому приходиться делать предварительный поиск, чтобы уменьшить число непосредственно просматриваемых файлов до нескольких тысяч. Вот отсюда и появился массив на входе, который не умещается в командной строке.
Inline позволяет выполнять код С, но не обеспечивает его быстродействие - из за количества данных здесь годится только С или ассемблер, причем последний нежелателен ради кроссплатформенности.
Может быть, кто-нибудь знает, нельзя ли оформить программу в кодах как .pm модуль?

Автор: korob2001 8.8.2008, 10:04
Цитата(Rigel @  8.8.2008,  05:38 Найти цитируемый пост)
Inline позволяет выполнять код С, но не обеспечивает его быстродействие - из за количества данных здесь годится только С или ассемблер, причем последний нежелателен ради кроссплатформенности.

Помоему C такой же кроссплатформенный, как и Asm. В любом случае нужно будет компилировать заново, при каждом переносе. Потому я и сказал, что для кроссплатформенности придётся писать на Perl или Java.

С другой стороны, когда используешь Inline, то все эти компиляции при переносе происходят совершенно прозрачно, лишь бы там был компилятор.

Если честно, я не понял почему вы считаете, что код скомпилированный Inline будет работать медленнее, чем код, который будет скомпилен вручную? Честно говоря, мне никогда не приходилось использовать Inline::C, но зато приходилось использовать Inline::Java. При первом запуске Perl компилирует Inline код и сохраняет его в специальном каталоге, в итоге я получил уже скомпилированные классы Java например из кода, ссылку на который я вам давал выше,  у меня получился полноценный Java класс Person.class . При следующем запуске, код выполняется намного быстрее, потому как нет необходимости компилировать Inline код повторно, разумеется если не изменялся код программы на Perl, который использует Inline. Так что думаю код скомпиленный Inline, будет работать с той же скоростью, что и код скомпиленный вручную, к тому же Inline компилирует этот модуль тем компилятором, который вы сами ему укажете.
Пробовал я написать программу на Java, которая использует сгенерированный Inline модулем, класс. Работает он так же, как если бы я писал его на чистом Java.

Автор: gcc 19.8.2008, 23:29
получаеться, что perl на ходу компилирует C и Java !!?

а можно написать демона который будет слушать запросы из perl скрипт...
быстродействие будет? писали где-то, что perl работает с opengl не медленее чем С++
еще видел так используеться php c C

кстате, а где про это можно почитать? если кто-то интересовался?  smile 

Автор: GreenFactory 20.8.2008, 17:52
Уверен, что вам подойдёт
http://search.cpan.org/search?query=IPC%3A%3AOpen&mode=module
Правда это достаточно опасно из-за взаимных блокировок, но т.к. обе программы пишете вы, проблем не должно быть


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)