2010-08-03 4 views
3

У меня есть скрипт Perl и необходимо вызвать метод, который находится в сборке .NET. Я нашел this technique, но он довольно востребован для одноразового скрипта Perl, поэтому я его не использовал. Я закончил тем, что написал тривиальное консольное приложение .NET в качестве обертки для нужного мне вызова и связал мой скрипт на Perl с оберткой, используя Console.In/Console.Out/IPC::Open2.Вызов .NET из Perl

Это оказалось проблематичным, поскольку метод NET StreamReader.ReadToEnd не смог обнаружить конец файла на Console.In, даже после того, как мой скрипт Perl закрыл его конец!

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

+0

Я не работал с Perl. Сказав это, вы можете экспортировать свою сборку в COM видимую (tlbexp) и используя COM-библиотеку из perl? – shahkalpesh

+0

Вы видели PerlNet? http://docs.activestate.com/pdk/8.0/PerlNET_overview.html – Abel

+0

PerlNet, похоже, подходит только для ActiveState? Я использую Strawberry – JoelFan

ответ

3

«метод StreamReader.ReadToEnd, похоже, не в состоянии обнаружить оконечные-файла на консоли.Мастер»

Вы, кажется, был в состоянии взаимодействовать с .NET. Но вы набрали StreamReader.ReadToEnd на консольном входе. Это может быть проблематично даже без Perl. Выдержка из почему это:

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

Возможно, ваш код прав, но для этого вам нужно использовать другой метод.

Edit:

"Я в конечном итоге писать тривиальное приложение .NET консольного как обертка"

Мне кажется, что вы пытаетесь общаться между двумя (Perl и .NET). Протокол, который вы выбрали (Console.In/Out), может работать, но вы должны использовать StreamReader.Read или StreamReader.ReadLine в своем .NET-приложении в цикле, чтобы вы могли легко обнаружить, когда поток закрыт. Операции чтения возвращают null, когда они находятся в EOF.

В качестве альтернативы вы можете использовать любой метод, который понравится вам в Perl и вызвать его из .NET. I.e., вы меняете логику, и .NET просто спрашивает, взаимодействуя с вашим кодом Perl, для ввода. Затем вы можете использовать Perl для своей основной задачи программирования. Вы можете сделать это, используя PerlSharp.

+0

Я закончил тем, что передал байтовую длину в качестве параметра командной строки в приложение-оболочку-оболочку и имел консольное приложение «ReadBlock» вместо «ReadToEnd» – JoelFan

+0

. Я не думаю, что переключение на Read/ReadLine будет работать лучше ReadToEnd. Вы говорите, что операции Read возвращают null, когда они находятся в EOF, но проблема в том, что они не могут обнаружить EOF на трубе. Они просто блокируют, когда я закончу писать, как ReadToEnd – JoelFan

+0

@JoelFan: Это не соответствует документации .NET, см. Ссылку на ReadToEnd в моем сообщении. Однако, я могу сделать небольшой тест, конечно, посмотреть, что происходит. Btw, 'ReadBlock' в основном работает так же, как' Read', он внутренне называет 'Read' в любом случае, поэтому, если это сработает для вас, оба подхода должны работать. Mmm, все, что касается, я предполагаю только без EOF-флага ;-) – Abel