Читать «UNIX: взаимодействие процессов» онлайн - страница 293
Уильям Ричард Стивенс
15 out.arg2.arg2_len = 1;
16 out.arg2.arg2_val = &lval2;
17 lval3 = 123;
18 out.arg3 = &lval3;
19 buff = Malloc(BUFFSIZE); /* адрес должен быть кратен 4 */
20 xdrmem_create(&xhandle, buff, BUFFSIZE, XDR_ENCODE);
21 if (xdr_args(&xhandle, &out) != TRUE)
22 err_quit("xdr_args error");
23 size = xdr_getpos(&xhandle);
24 lptr = (long *) buff;
25 for (i = 0; i < size; i += 4)
26 printf("%ld\n", (long) ntohl(*lptr++));
27 exit(0);
28 }
Присваивание значений
12-18 Для присваивания значения объединению мы устанавливаем дискриминант в TRUE, а затем присваиваем значение полю long. Длину массива мы также сначала устанавливаем в 1. Указатель мы устанавливаем на соответствующее значение в памяти.
При запуске этой программы мы получим ожидаемые шесть 4-байтовых значений:
solaris % opt1
1
5
1
9876
1
123
Пример: обработка связного списка
Если осуществима передача необязательных данных, мы можем расширить возможности указателей в XDR и использовать их для кодирования и декодирования связных списков, содержащих произвольное количество элементов. В нашем примере используется связный список пар имя-значение. Соответствующий файл спецификации XDR приведен в листинге 16.21.
Листинг 16.21. Спецификация XDR для связного списка пар имя-значение
//sunrpc/xdr1/opt2.x
1 struct mylist {
2 string name<>;
3 long value;
4 mylist *next;
5 };
6 struct args {
7 mylist *list;
8 };
1-5 Структура mylist содержит одну пару имя-значение и указатель на следующую структуру такого типа. Указатель в последней структуре списка будет нулевым.
В листинге 16.22 приведен текст заголовочного файла, созданного программой rpcgen из файла opt2.х.
Листинг 16.22. Заголовочный файл, созданный программой rpcgen
//sunrpc/xdr1/opt2.h
7 struct mylist {
8 char *name;
9 long value;
10 struct mylist *next;
11 };
12 typedef struct mylist mylist;
13 struct args {
14 mylist *list;
15 };
16 typedef struct args args;
В листинге 16.23 приведен текст программы, инициализирующей связный список с тремя парами имя-значение и кодирующей его с помощью библиотеки XDR.
Листинг 16.23. Инициализация, кодирование связного списка и вывод результата
1 //sunrpc/xdr1/opt2.c
2 #include "unpipc.h"
3 #include "opt2.h"
4 int
5 main(int argc, char **argv)
6 {
7 int i;
8 XDR xhandle;
9 long *lptr;
10 args out; /* структура, которую мы заполняем */
11 char *buff; /* результат кодирования */
12 mylist nameval[4]; /* до четырех элементов в списке */
13 size_t size;
14 out.list = &nameval[2]; /* [2] –> [1] –> [0] */
15 nameval[2].name = "name1";
16 nameval[2].value = 0x1111;
17 nameval[2].next = &nameval[1];
18 nameval[1].name = "namee2";
19 nameval[1].value = 0x2222;
20 nameval[1].next = &nameval[0];
21 nameval[0].name = "nameee3";
22 nameval[0].value = 0x3333;
23 nameval[0].next = NULL;
24 buff = Malloc(BUFFSIZE); /* адрес должен быть кратен 4 */
25 xdrmem_create(&xhandle, buff, BUFFSIZE, XDR_ENCODE);