> For the complete documentation index, see [llms.txt](https://book.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.bsdcn.org/man/xdr/xdr.3.md).

# xdr.3

`xdr` — 外部数据表示的库例程

## 名称

`xdr`, `xdr_array`, `xdr_bool`, `xdr_bytes`, `xdr_char`, `xdr_destroy`, `xdr_double`, `xdr_enum`, `xdr_float`, `xdr_free`, `xdr_getpos`, `xdr_hyper`, `xdr_inline`, `xdr_int`, `xdr_long`, `xdr_longlong_t`, `xdrmem_create`, `xdr_opaque`, `xdr_pointer`, `xdrrec_create`, `xdrrec_endofrecord`, `xdrrec_eof`, `xdrrec_skiprecord`, `xdr_reference`, `xdr_setpos`, `xdr_short`, `xdr_sizeof`, `xdrstdio_create`, `xdr_string`, `xdr_u_char`, `xdr_u_hyper`, `xdr_u_int`, `xdr_u_long`, `xdr_u_longlong_t`, `xdr_u_short`, `xdr_union`, `xdr_vector`, `xdr_void`, `xdr_wrapstring`

## 库

Lb libc

## 概要

`#include <rpc/types.h>`

`#include <rpc/xdr.h>`

函数声明参见描述一节。

## 描述

这些例程允许 C 程序员以机器无关的方式描述任意数据结构。远程过程调用的数据使用这些例程传输。

```c
int
xdr_array(XDR *xdrs, char **arrp, u_int *sizep,
    u_int maxsize, u_int elsize, xdrproc_t elproc);
```

一种过滤器原语，用于在变长数组及其对应的外部表示之间进行转换。`arrp` 参数是指向数组指针的地址，`sizep` 参数是数组元素计数地址；该元素计数不能超过 `maxsize`。`elsize` 参数是每个数组元素的 `sizeof`，`elproc` 是一个 XDR 过滤器，用于在数组元素的 C 形式及其外部表示之间转换。成功时返回 1，否则返回 0。

```c
int
xdr_bool(XDR *xdrs, bool_t *bp);
```

一种过滤器原语，用于在布尔值（C 整数）及其外部表示之间转换。编码数据时，此过滤器产生值 1 或 0。成功时返回 1，否则返回 0。

```c
int
xdr_bytes(XDR *xdrs, char **sp, u_int *sizep, u_int maxsize);
```

一种过滤器原语，用于在计数字节字符串及其外部表示之间转换。`sp` 参数是指向字符串指针的地址。字符串的长度位于地址 `sizep` 处；字符串长度不能超过 `maxsize`。成功时返回 1，否则返回 0。

```c
int
xdr_char(XDR *xdrs, char *cp);
```

一种过滤器原语，用于在 C 字符及其外部表示之间转换。成功时返回 1，否则返回 0。注意：编码后的字符不进行打包，每个字符占用 4 字节。对于字符数组，建议考虑 `xdr_bytes`、`xdr_opaque` 或 `xdr_string`。

```c
void
xdr_destroy(XDR *xdrs);
```

一个宏，调用与 XDR 流 `xdrs` 关联的销毁例程。销毁通常涉及释放与该流关联的私有数据结构。调用 `xdr_destroy` 之后使用 `xdrs` 的行为未定义。

```c
int
xdr_double(XDR *xdrs, double *dp);
```

一种过滤器原语，用于在 C `double` 精度数字及其外部表示之间转换。成功时返回 1，否则返回 0。

```c
int
xdr_enum(XDR *xdrs, enum_t *ep);
```

一种过滤器原语，用于在 C `enum`（实际上是整数）及其外部表示之间转换。成功时返回 1，否则返回 0。

```c
int
xdr_float(XDR *xdrs, float *fp);
```

一种过滤器原语，用于在 C `float` 及其外部表示之间转换。成功时返回 1，否则返回 0。

```c
void
xdr_free(xdrproc_t proc, void *objp);
```

通用释放例程。第一个参数是所释放对象的 XDR 例程。第二个参数是指向对象本身的指针。注意：传递给此例程的指针*不会*被释放，但它所指向的内容*会*被（递归地）释放。

```c
u_int
xdr_getpos(XDR *xdrs);
```

一个宏，调用与 XDR 流 `xdrs` 关联的获取位置例程。该例程返回一个无符号整数，指示 XDR 字节流的位置。XDR 流的一个理想特性是简单的算术运算可以用于此数字，尽管 XDR 流实例不必保证这一点。

```c
int
xdr_hyper(XDR *xdrs, quad_t *llp);
```

一种过滤器原语，用于在 ANSI C `long long` 整数及其外部表示之间转换。成功时返回 1，否则返回 0。

```c
long *
xdr_inline(XDR *xdrs, int len);
```

一个宏，调用与 XDR 流 `xdrs` 关联的内联例程。该例程返回指向流缓冲区中连续块的指针；`len` 是所需缓冲区的字节长度。注意：指针被转换为 `long *`。警告：如果无法分配连续的缓冲区块，`xdr_inline` 可能返回 `NULL`（0）。因此，不同流实例的行为可能不同；它的存在是为了提高效率。

```c
int
xdr_int(XDR *xdrs, int *ip);
```

一种过滤器原语，用于在 C 整数及其外部表示之间转换。成功时返回 1，否则返回 0。

```c
int
xdr_long(XDR *xdrs, long *lp);
```

一种过滤器原语，用于在 C `long` 整数及其外部表示之间转换。成功时返回 1，否则返回 0。

```c
int
xdr_longlong_t(XDR *xdrs, quad_t *llp);
```

一种过滤器原语，用于在 ANSI C `long long` 整数及其外部表示之间转换。成功时返回 1，否则返回 0。

```c
void
xdrmem_create(XDR *xdrs, char *addr, u_int size, enum xdr_op op);
```

此例程初始化 `xdrs` 所指向的 XDR 流对象。流的数据写入到或读取自位于 `addr` 的一块内存，其长度不超过 `size` 字节。`op` 参数决定 XDR 流的方向（`XDR_ENCODE`、`XDR_DECODE` 或 `XDR_FREE`）。

```c
int
xdr_opaque(XDR *xdrs, char *cp, u_int cnt);
```

一种过滤器原语，用于在固定大小的不透明数据及其外部表示之间转换。`cp` 参数是不透明对象的地址，`cnt` 是其字节大小。成功时返回 1，否则返回 0。

```c
int
xdr_pointer(XDR *xdrs, char **objpp, u_int objsize,
    xdrproc_t xdrobj);
```

类似于 `xdr_reference`，不同之处在于它可以序列化 `NULL` 指针，而 `xdr_reference` 不能。因此，`xdr_pointer` 可以表示递归数据结构，如二叉树或链表。

```c
void
xdrrec_create(XDR *xdrs, u_int sendsize, u_int recvsize,
    void *handle, int (*readit)(void *, void *, int),
    int (*writeit)(void *, void *, int));
```

此例程初始化 `xdrs` 所指向的 XDR 流对象。流的数据写入大小为 `sendsize` 的缓冲区；值为零表示系统应使用合适的默认值。流的数据从大小为 `recvsize` 的缓冲区读取；同样可以通过传递零值来设置为合适的默认值。当流的输出缓冲区满时，调用 `writeit`。类似地，当流的输入缓冲区为空时，调用 `readit`。这两个例程的行为类似于系统调用 [read(2)](https://github.com/FreeBSD-Ask/freebsd-man-sc/tree/main/man2/read.2.md) 和 [write(2)](https://github.com/FreeBSD-Ask/freebsd-man-sc/tree/main/man2/write.2.md)，不同之处在于 `handle` 作为第一个参数传递给前述例程。注意：XDR 流的 `op` 字段必须由调用者设置。警告：此 XDR 流实现了中间记录流。因此流中有额外的字节用于提供记录边界信息。

```c
int
xdrrec_endofrecord(XDR *xdrs, int sendnow);
```

此例程只能在由 `xdrrec_create` 创建的流上调用。输出缓冲区中的数据被标记为一条完整的记录，如果 `sendnow` 非零，则可选地写出输出缓冲区。成功时返回 1，否则返回 0。

```c
int
xdrrec_eof(XDR *xdrs);
```

此例程只能在由 `xdrrec_create` 创建的流上调用。消耗流中当前记录的剩余部分后，如果流没有更多输入，此例程返回 1，否则返回 0。

```c
int
xdrrec_skiprecord(XDR *xdrs);
```

此例程只能在由 `xdrrec_create` 创建的流上调用。它告知 XDR 实现应丢弃流的输入缓冲区中当前记录的剩余部分。成功时返回 1，否则返回 0。

```c
int
xdr_reference(XDR *xdrs, char **pp, u_int size, xdrproc_t proc);
```

一种在结构内提供指针追踪的原语。`pp` 参数是指针的地址；`size` 是 `*pp` 所指向结构的 `sizeof`；`proc` 是一个 XDR 过程，用于在结构的 C 形式及其外部表示之间进行过滤。成功时返回 1，否则返回 0。警告：此例程不理解 `NULL` 指针。请改用 `xdr_pointer`。

```c
int
xdr_setpos(XDR *xdrs, u_int pos);
```

一个宏，调用与 XDR 流 `xdrs` 关联的设置位置例程。`pos` 参数是从 `xdr_getpos` 获取的位置值。如果 XDR 流可以重新定位，此例程返回 1，否则返回 0。警告：某些类型的 XDR 流难以重新定位，因此此例程可能对一种类型的流失败而对另一种成功。

```c
int
xdr_short(XDR *xdrs, short *sp);
```

一种过滤器原语，用于在 C `short` 整数及其外部表示之间转换。成功时返回 1，否则返回 0。

```c
unsigned long
xdr_sizeof(xdrproc_t func, void *data);
```

此例程返回使用过滤器 `func` 编码 `data` 所需的内存量。

```c
#ifdef _STDIO_H_
/* 使用 stdio 库的 XDR */
void
xdrstdio_create(XDR *xdrs, FILE *file, enum xdr_op op);
#endif
```

此例程初始化 `xdrs` 所指向的 XDR 流对象。XDR 流数据写入到或读取自标准 I/O 流 `file`。`op` 参数决定 XDR 流的方向（`XDR_ENCODE`、`XDR_DECODE` 或 `XDR_FREE`）。警告：与此类 XDR 流关联的销毁例程会对 `file` 流调用 [fflush(3)](https://github.com/FreeBSD-Ask/freebsd-man-sc/tree/main/man3/fflush.3.md)，但从不调用 [fclose(3)](https://github.com/FreeBSD-Ask/freebsd-man-sc/tree/main/man3/fclose.3.md)。

```c
int
xdr_string(XDR *xdrs, char **sp, u_int maxsize);
```

一种过滤器原语，用于在 C 字符串及其对应的外部表示之间转换。字符串长度不能超过 `maxsize`。注意：`sp` 是字符串指针的地址。成功时返回 1，否则返回 0。

```c
int
xdr_u_char(XDR *xdrs, unsigned char *ucp);
```

一种过滤器原语，用于在 `unsigned` C 字符及其外部表示之间转换。成功时返回 1，否则返回 0。

```c
int
xdr_u_hyper(XDR *xdrs, u_quad_t *ullp);
```

一种过滤器原语，用于在 `unsigned` ANSI C `long long` 整数及其外部表示之间转换。成功时返回 1，否则返回 0。

```c
int
xdr_u_int(XDR *xdrs, unsigned *up);
```

一种过滤器原语，用于在 C `unsigned` 整数及其外部表示之间转换。成功时返回 1，否则返回 0。

```c
int
xdr_u_long(XDR *xdrs, unsigned long *ulp);
```

一种过滤器原语，用于在 C `unsigned long` 整数及其外部表示之间转换。成功时返回 1，否则返回 0。

```c
int
xdr_u_longlong_t(XDR *xdrs, u_quad_t *ullp);
```

一种过滤器原语，用于在 `unsigned` ANSI C `long long` 整数及其外部表示之间转换。成功时返回 1，否则返回 0。

```c
int
xdr_u_short(XDR *xdrs, unsigned short *usp);
```

一种过滤器原语，用于在 C `unsigned short` 整数及其外部表示之间转换。成功时返回 1，否则返回 0。

```c
int
xdr_union(XDR *xdrs, enum_t *dscmp, char *unp,
    const struct xdr_discrim *choices, xdrproc_t defaultarm);
```

一种过滤器原语，用于在判别式 C `union` 及其对应的外部表示之间转换。它首先转换位于 `dscmp` 处的联合的判别式。此判别式始终是 `enum_t`。接下来转换位于 `unp` 处的联合。`choices` 参数是指向 `xdr_discrim` 结构数组的指针。每个结构包含一个有序对 \[`value`, `proc`]。如果联合的判别式等于关联的 `value`，则调用 `proc` 来转换联合。`xdr_discrim` 结构数组的末尾由值为 `NULL` 的例程表示。如果在 `choices` 数组中未找到判别式，则调用 `defaultarm` 过程（如果它不是 `NULL`）。成功时返回 1，否则返回 0。

```c
int
xdr_vector(XDR *xdrs, char *arrp, u_int size,
    u_int elsize, xdrproc_t elproc);
```

一种过滤器原语，用于在定长数组及其对应的外部表示之间转换。`arrp` 参数是指向数组指针的地址，`size` 是数组的元素计数。`elsize` 参数是每个数组元素的 `sizeof`，`elproc` 是一个 XDR 过滤器，用于在数组元素的 C 形式及其外部表示之间转换。成功时返回 1，否则返回 0。

```c
int
xdr_void(void);
```

此例程始终返回 1。可传递给需要函数参数的 RPC 例程，此时无需执行任何操作。

```c
int
xdr_wrapstring(XDR *xdrs, char **sp);
```

一种原语，调用 `xdr_string(xdrs, sp, MAXUN.UNSIGNED)`；其中 `MAXUN.UNSIGNED` 是无符号整数的最大值。`xdr_wrapstring` 函数很方便，因为 RPC 包最多传递两个 XDR 例程作为参数，而 `xdr_string` 作为最常用的原语之一需要三个参数。成功时返回 1，否则返回 0。

## 参见

[rpc(3)](https://github.com/FreeBSD-Ask/freebsd-man-sc/tree/main/man3/rpc.3.md)

> "eXternal Data Representation Standard: Protocol Specification".

> "eXternal Data Representation: Sun Technical Notes".

> "XDR: External Data Representation Standard", RFC1014.

## 历史

`xdr_sizeof` 函数首次出现于 FreeBSD 9.0。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://book.bsdcn.org/man/xdr/xdr.3.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
