Главная страница Взаимодействие нетривиальных процессов Листинг 16.17 (продолжение) 10 long *агдЗ; /* указатель */ 11 }: Объявление объединения с булевским дискриминантом 1-В Мы определяем объединение с ветвями FALSE и TRUE и структуру этого типа. Если флаг дискриминанта TRUE, за ним следует значение типа long; в противном случае за ним ничего не следует. После кодирования библиотекой XDR это объединение будет закодировано как: :t 4 байта флага со значением 1 (TRUE) и 4 байта целочисленного значения либо ш 4 байта флага со значением О (FALSE). Объявление массива переменной длины 9 Если мы указываем массив переменной длины с одним возможным элементом, он будет передан как: ш 4 байта со значением 1 и 4 байта значения либо * 4 байта со значением 0. Объявление указателя XDR 10 Новый способ определения необязательных данных заключается в объявлении указателя. Он будет закодирован как: ж 4 байта со значением 1 и 4 байта значения либо 4 байта со значением О в зависимости от значения соответствующего указателя при кодировании данных. Если указатель ненулевой, используется первый вариант кодирования. Если указатель нулевой, получится второй вариант. Это удобный способ кодирования необязательных данных в случае, если в нащем коде имеется указатель на эти данные. Важная деталь реализации, благодаря которой оба варианта дают одинаковый результат при кодировании, заключается в том, что значение TRUE равно 1, что совпадает с длиной массива переменной длины, когда в нем есть один элемент. В листинге 16.18 приведен текст заголовочного файла, созданного программой rpcgen для данного файла спецификации. Листинг 16.18. Заголовочный файл, получившийся в результате обработки листинга 16.17 sunrpc/xdrl/optl.h 7 struct optlong { 8 bool t flag: 9 union { 10 long val: 11 } optlong u: 12 }: 13 typedef struct optlong optlong: 14 struct args { 15 optlong argl: 16 struct { 17 u int arg2 len: IB long *arg2 val: 19 } arg2: 20 long *arg3; 21 }: 22 typedef struct args args: 14-21 Хотя все три аргумента кодируются одинаково, способы присваивания и получения их значений в языке С различны. В листинге 16.19 приведен текст простой программы, устанавливающей значения всех трех аргументов так, что ни одно из полей 1 ong не кодируется. Листинг 16.19. Ни одно из значений не будет закодировано sunrpc/xdrl/optlz.c 1 #include unpipc.h 2 #include optLh 3 int 4 mainCint argc, char **argv) 6 i nt i; 7 XDR xhandle: 8 char *buff: 9 long *lptr; 10 args out: 11 size t size: 12 out.argl.flag = FALSE: 13 out.arg2,arg2 len = 0: 14 out.arg3 = NULL: 15 buff = Malloc(BUFFSIZE); /* Адрес должен быть кратен четырем */ 16 xdrmem create(&xhandle, buff, BUFFSIZE. XDRJNCODE): 17 if (xdr args(&xhandle. Sout) != TRUE) IB err quit( xdr args error ): 19 size = xdr getpos(&xhandle): 20 Iptr = (long *) buff: 21 for (i = 0; i < size: i += 4) 22 printf( ld\n . (long) ntohl(*lptr++)): 23 exit(O): 24 } Присваивание значений 12-14 Дискриминанту объединения присваивается значение FALSE, длина массива переменной длины устанавливается в О, а указатель делается нулевым (NULL). Выделение буфера и кодирование 15-19 Мы выделяем буфер и кодируем структуру out в поток XDR. Вывод содержимого буфера XDR 20-22 Мы выводим содержимое буфера XDR по 4 байта, используя функцию ntohl (host-to-network long integer) для преобразования из порядка XDR big-endian в байтовый порядок узла. В результате получается именно то, что должно было быть помещено в буфер библиотекой XDR времени выполнения: Solaris % optlz Как мы и предполагали, каждому аргументу отводится 4 байта со значением О, указывающим на то, что за ним не следует никаких данных. В листинге 16.20 приведена измененная версия программы, которая присваивает значения всем трем аргументам, кодирует их в поток XDR и выводит его содержимое. Листинг 16.20. Присваивание значений аргументам из листинга 16.17 sunrpc/xdrl/optl.c 1 linclude unpipc.h 2 linclude optl.h 3 int 4 mainCint argc. char **argv) 6 int i: 7 XDR xhandle: 8 char *buff: 9 long lval2. Ival3, *lptr: 10 args out; 11 size t size: 12 out.argl,flag = TRUE; 13 out,argl,optlong u,val - 5: 14 lval2 = 9B76: 15 out,arg2,arg2 len = 1; 16 out,arg2,arg2 val = &lval2: 17 lval3 = 123: IB out,arg3 = &lval3; 19 buff - Malloc(BUFFSIZE): /* адрес должен быть кратен 4 */ 20 xdrmern create(&xhandle. buff. BUFFSIZE, XDRJNCODE): 21 if (xdr args(&xhandle, &out) !- TRUE) 22 err quit( xdr args error ): 23 size - xdr getpos(&xhandle): 24 Iptr = (long *) buff: 25 for (i = 0: i < size: i += 4) 26 printf( ld\n . (long) ntohl(*lptr++)): 27 exit(O): 2B }
|
© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования. |