Вход/Регистрация
UNIX: взаимодействие процессов
вернуться

Стивенс Уильям Ричард

Шрифт:

34 printf("uarg (int) = %d\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);

38 break;

39 default:

40 printf("uarg (void)\n");

41 break;

42 }

43 xdr_free(xdr_data, (char*)&in);

44 exit(0);

45 }

Выделение правильно расположенного буфера

11-13 Вызывается функция malloc для выделения буфера. В этот буфер считывается файл, созданный предыдущей программой.

Создание потока XDR, инициализация буфера, декодирование

14-17 Инициализируем поток XDR, указав флаг XDR_DECODE, означающий, что преобразование производится из формата XDR в формат узла. Мы инициализируем структуру i n нулями и вызываем xdr_data для декодирования содержимого буфера buff в эту структуру. Мы обязаны инициализировать принимающую структуру нулями, поскольку некоторые из подпрограмм XDR (например, xdr_string) требуют выполнения этого условия. xdr_data — это та же функция, которую мы вызывали в листинге 16.13. Изменился только последний аргумент xdrmem_create: в предыдущей программе мы указывали XDR_ENCODE, а в этой — XDR_DECODE. Это значение сохраняется в дескрипторе XDR (xhandle) функцией xdrmem_create и затем используется библиотекой XDR для выбора между кодированием и декодированием данных.

Вывод значений полей структуры

18-42 Мы выводим значения всех полей структуры data.

Освобождение выделенной под XDR памяти

43 Для освобождения памяти мы вызываем функцию xdr_free (см. упражнение 16.10).

Запустим программу write на компьютере Sparc, перенаправив стандартный вывод в файл с именем data:

solaris % write > data

solaris % ls -l data

– rw-rw-r-- 1 rstevens other1 76 Apr 23 12:32 data

Мы видим, что размер файла равен 72 байтам что соответствует рис. 16.4, на котором изображена схема хранения данных.

Прочитав этот файл в BSD/OS или Digital Unix, мы получим те результаты, на которые и рассчитывали:

bsdi % read < data

read 76 bytes

short_arg = 1, long_arg = 2, vstring_arg = 'hello, world'

fopaque[] =99, 88, 77

vopaque<> = 33 44

fshort_arg[] = 9999, 8888, 7777, 6666

vlong<> = 123456 234567 345678

uarg (int) = 123

alpha % read < data

read 76 bytes

short_arg = 1, long_arg = 2, vstring_arg = 'hello, world'

fopaque[] = 99, 88, 77

vopaque<> = 33 44

fshort_arg[] = 9999, 8888, 7777, 6666

vlong<> = 123456 234567 345678

uarg (int) = 123

Рис. 16.4. Формат потока XDR, записанный в листинге 16.13

Пример: вычисление размера буфера

В предыдущем примере мы выделяли буфер размера BUFFSIZE (определенного в файле unpiрс.h в листинге В.1), и этого было достаточно. К сожалению, не существует простого способа вычислить объем памяти, нужный XDR для кодирования конкретных данных. Вычислить размер структуры вызовом sizeof недостаточно, потому что каждое поле кодируется XDR по отдельности. Нам придется перебирать элементы структуры, прибавляя к конечному результату объем памяти, нужный XDR для кодирования очередного элемента. В листинге 16.15 приведен пример простой структуры с тремя полями.

Листинг 16.15. Спецификация XDR для простой структуры

//sunrpc/xdrl/examplе.х

1 const MAXC = 4;

2 struct example {

3 short a;

4 double b;

5 short c[MAXC];

6 };

Программа, текст которой приведен в листинге 16.16, вычисляет размер буфера, требуемого XDR для кодирования этой структуры. Он получается равным 28 байт.

Листинг 16.16. Программа, вычисляющая размер буфера XDR

//sunrpc/xdr1/example.c

1 #include "unpipc.h"

2 #include "example.h"

3 int

4 main(int argc, char **argv)

5 {

6 int size;

7 example foo;

8 size = RNDUP(sizeof(foo.a)) + RNDUP(sizeof(foo.b)) +

9 RNDUP(sizeof(foo.c[0])) * MAXC;

10 printf("size = %d\n", size);

  • Читать дальше
  • 1
  • ...
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: