Главная страница Взаимодействие нетривиальных процессов Листинг 16.12 (продолжение) 36 typedef struct data data: 37 /* 4the xdr functions */ 38 extern bool t xdr result t(XDR *, result t*): 39 extern bool t xdr union arg(XDR *, union~arg*): 40 extern bool t xdr data(XDR *. data*): 41 #endif /* ! DATA H RPCGEN */ В файле data xdr. с объявляется функция xdr data, вызываемая для кодирования и декодирования структуры data, которую мы определили. Суффикс имени функции data соответствует имени нашей структуры из листинга 16.11. Первая программа, которую мы напишем, будет называться write.с. Она будет присваивать значения полям структуры data, вызывать xdr data для кодирования всех полей в формат XDR и записывать результат в стандартный поток вывода. Эта программа приведена в листинге 16.13. Листинг 16.13. Инициализация структуры и кодирование ее bXDR sunrpc/xdrl/write.c 1 #include unpipc.h 2 #include data.h 3 int 4 mainCint argc. char **argv) 6 XDR xhandle: 7 data out: /* структура, с которой мы работаем */ 8 char *buff: /* результат кодирования в XDR */ 9 char vop[2]: 10 long vlong[3]: 11 ujnt size: 12 out.short arg = 1: 13 out.long arg = 2; 14 out.vstring arg = hello, world : /* присваиваем значение указателю */ 15 out.fopaque arg[0] = 99 16 out.fopaque arg[l] = 88 17 out.fopaque arg[2] = 77 /* скрытые данные фиксированной длины */ 18 vop[0] =33: /* скрытые данные переменной длины */ 19 vop[l] = 44: 20 out.vopaque arg.vopaque arg len = 2: 21 out.vopaque arg.vopaque arg val = vop: 22 out.fshort arg[0] = 9999 23 out.fshort arg[l] = 8888 24 out.fshort arg[2] = 7777 25 out.fshort arg[3] = 6666 26 vlong[0] = 123456: 27 vlong[l] = 234567; 28 vlong[2] = 345678; 29 out,vlong arg.vlong arg len = 3: /* массив фиксированной длины */ /* массив переменной длины */ 30 out.vlong arg.vlong arg val = vlong; 31 out.uarg,result = RESULT INT: /* размеченное объединение */ 32 out.uarg.union arg u.intval = 123; 33 buff = Malloc(BUFFSIZE); /* кратен 4-м байтам */ 34 xdrmem create(&xhandle. buff. BUFFSIZE, XDRJNCODE); 35 if (xdr data(&xhandle. Sout) != TRUE) 36 err quit( xdr data error ); 37 size = xdr getpos(&xhandle); 3B WriteCSTDOUTJILENO. buff, size): 39 exitCO): 40 } Инициализация элементов структуры ненулевыми значениями 12-32 Сначала мы присваиваем полям структуры ненулевые значения. В случае полей переменной длины мы должны установить длину этих полей. Мы присваиваем дискриминанту размеченного объединения значение RESULT INT и помещаем в его соответствующее поле значение 123. Выделение буфера 33 Мы вызываем mal 1 ос для выделения буфера, в который подпрограммы XDR будут помещать результаты своей работы. Адрес и размер буфера должны быть кратны четырем. Выделение массива char не гарантирует этого. Создание потока XDR в памяти 34 Функция библиотеки времени выполнения xdrmem create инициализирует буфер, на который указывает buff, предназначенный для использования функциями XDR как поток в памяти. Мы вьщеляем переменную типа XDR с именем xhandl е и передаем адрес этой переменной в качестве первого аргумента. Библиотека XDR времени выполнения хранит в этой переменной всю необходимую информацию (указатель на буфер, текущее положение в буфере и т. п.). Последний аргумент имеет значение XDR ENCODE, что указывает XDR на необходимость преобразования данных из формата узла в формат XDR. Кодирование структуры 35-36 Мы вызываем функцию xdr data, созданную rpcgen в файле data xdr,c, и она кодирует структуру out в формат XDR. Возвращаемое значение TRUE говорит об успешном заверщении работы функции. Получение размера кодированных данных и запись их в поток вывода 37-38 Функция xdr getpos возвращает текущее положение библиотеки XDR в выходном буфере (то есть сдвиг байта, в который будут помещены очередные данные). Его мы трактуем как размер готовых к записи данных. В листинге 16.14 приведен текст программы read, которая считывает данные из файла, записанного предыдущей программой, и выводит значения всех полей структуры data. Листинг 16.14. Считывание структуры data из формата XDR sunrpc/xdrl/read.c 1 linclude unpipc.h 2 linclude data.h 3 int 4 maindnt argc. char **argv) 6 XDR xhandle; 7 int i; 8 char *buff; 9 data in; 10 ssize t n: 11 buff = Malloc(BUFFSIZE); /* адрес должен быть кратен 4-м байтам */ 12 п = Read(STDIN FILENO. buff. BUFFSIZE): 13 printf( read *ld bytesNn . (long) n); 14 xdrmem create(&xhandle. buff, n, XDR DECODE); 15 memset(&in. 0. sizeof(in)); 16 if (xdr data(&xhandle. &in) != TRUE) 17 err quit( xdr data error ); IB printf( short arg = %й. long arg = %й. vstring arg = Xs\n , 19 1n,short arg, in.long arg, in.vstring arg): 20 printf( fopaque[] = %й. %й. %й\г\ . 21 in.fopaque arg[0]. in.fopaque arg[l]. in.fopaque arg[2]); 22 printf( vopaque<> = ): 23 for (i = 0; i < 1n,vopaque arg.vopaque arg len; i++) 24 printf( Xd . in.vopaque arg,vopaque arg val[i]): 25 printf( \n ): 26 printf( fshort arg[] = Xd. Xd. Xd. Xd\n . in.fshort arg[0]. 27 in.fshort arg[l], in.fshort arg[2]. in.fshort arg[3]): 2B printf( vlong<> = ): 29 for (i = 0: i < in.vlong arg.vlong arg len: i++) 30 printf( X]d . in.vlong arg,vlong arg val[i]): 31 printf( \n ): 32 switch (in.uarg.result) { 33 case RESULT INT: 34 printf( uarg (int) = Xd\n , in,uarg.union arg u.intval): 35 break; 36 case RESULT DOUBLE: 37 printf( uarg (double) = *g\n , in.uarg.union arg u.doubleval): 3B break; 39 default: 40 printf( uarg (void)\n ); 41 break:
|
© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования. |