2013-09-25 3 views
4

У меня есть множество подпрограмм M-Code, поставляемых поставщиком, в составе гораздо более крупного продукта, который использует READ и WRITE непосредственно для взаимодействия с текущим устройством. Я не могу изменить этот код. Я хочу обернуть некоторые из этих подпрограмм в системе, где я могу обеспечить ввод и вывод вывода в интерактивном режиме.Перенаправление тока IO-устройства для взаимодействия сторонних сторон

В настоящее время это реализовано путем открытия TCP-соединения с удаленным хостом и создания текущего устройства. READ и WRITE действительно подключены к розетке. Это довольно неудобно, так как требуется, чтобы отдельная служба, которая прослушивает TCP-сокет, настраивалась и координировалась с локальным заданием, чтобы весь процесс работал. Я также должен отключить наглость и пропустить буферизацию, или соединение становится латентным или закрытым. (например, опция ОТКРЫТО TCP /SEN=1 aka +Q). К сожалению, это приводит к множеству 1-байтовых сегментов TCP и также очень неэффективно.

Я бы предпочел бы управлять всем взаимодействием через один процесс. В идеале я мог бы звонить на READ, WRITE, а другие функции, которые работают с текущим устройством, запускают некоторые M-коды или обратные вызовы в Caché Callin C interface или модуль расширения пользователя, чтобы обеспечить требуемые функции на задней панели. Таким образом, я могу управлять IO на своих собственных условиях без необходимости координации между процессами. Тем не менее, я не смог найти точку входа.

Есть ли такая вещь, как пользовательское устройство в Caché?

Для хостов UNIX существует способ использовать существующий файловый дескриптор в качестве устройства, что может быть полезно, но, похоже, оно не реализовано в Windows.

Одна вещь, которую я рассмотрел это, чтобы создать новый процесс, есть Windows, перенаправлять STDIN и STDOUT с SetStdHandle к трубам я контролирую из того же процесса, используйте Callin для подключения к Caché и пусть это использовать устройство по умолчанию, который, как предполагается, должно быть STDIN и STDOUT. Кто-нибудь знает, действительно ли это работает?

ответ

7

Caché фактически поддерживает произвольное перенаправление ввода-вывода. Это возможно с недокументированной функцией. Не рекомендуется, но вряд ли изменится.

Аннотированный код приведен ниже. В этом примере я выбираю перенаправить IO на% Stream.GlobalBinary - вы можете, как вам нравится, с ним. Ключ - это конкретные имена меток - вы можете указать другую процедуру с использованием $ io :: call и указать эти метки в другом месте.

//The ProcedureBlock = 0 is important 
// it allows for calling of labels within the ClassMethod 
ClassMethod testIORedirection() [ ProcedureBlock = 0 ] 
{ 
    //Create a stream that we will redirect to 
    set myStream = ##class(%Stream.GlobalBinary).%New() 

    //Redirect IO to the current routine - makes use of the labels defined below 
    use $io::("^"_$ZNAME) 

    //Enable redirection 
    do ##class(%Device).ReDirectIO(1) 

    //Any write statements here will be redirected to the labels defined below 
    write "Here is a string", !, ! 
    write "Here is something else", ! 

    //Disable redirection 
    do ##class(%Device).ReDirectIO(0) 

    //Print out the stream, to prove that it worked 
    write "Now printing the string:", ! 
    write myStream.Read() 


    //Labels that allow for IO redirection 
    //Read Character - we don't care about reading 
rchr(c)  quit 
    //Read a string - we don't care about reading 
rstr(sz,to) quit 
    //Write a character - call the output label 
wchr(s)  do output($char(s)) quit 
    //Write a form feed - call the output label 
wff()  do output($char(12)) quit 
    //Write a newline - call the output label 
wnl()  do output($char(13,10)) quit 
    //Write a string - call the output label 
wstr(s)  do output(s) quit 
    //Write a tab - call the output label 
wtab(s)  do output($char(9)) quit 
    //Output label - this is where you would handle what you actually want to do. 
    // in our case, we want to write to myStream 
output(s) do myStream.Write(s) quit 
} 
+0

Удивительно, это именно то, что я искал. Спасибо! –