C语言函数大全
本篇介绍C语言函数大全-- x 开头的函数
1. xdr_accepted_reply
1.1 函数说明
bool_t xdr_accepted_reply(XDR *xdrs, struct accepted_reply *ar);
用于将 RPC
(远程过程调用)应答中的 accepted_reply
结构体编码为 XDR
格式,或者从 XDR
数据流中解码 accepted_reply
结构体
参数:
- xdrs : 指向 XDR 数据流的指针
- ar: 指向 accepted_reply 结构体的指针。其中
accepted_reply
结构定义在<rpc/rpc.h>
头文件中
1.2 演示示例
1.2.1 accepted_reply
struct accepted_reply {
enum accept_stat ar_stat; /* status code */
union {
struct {
uint32_t low; /* lower half of range */
uint32_t high; /* upper half of range */
} ar_vers; /* new program version */
caddr_t ar_results; /* pointer to results */
auth_stat ar_why; /* why the call was rejected */
} ar_u; /* union of results */
};
1.2.2 Test.c
#include <stdio.h>
#include <rpc/rpc.h>
int main()
{
XDR xdrs;
char buffer[1024];
enum accept_stat status = RPC_SUCCESS;
// Encode an accepted_reply structure.
struct accepted_reply ar = {0};
ar.ar_stat = status;
xdrmem_create(&xdrs, buffer, sizeof(buffer), XDR_ENCODE);
if (!xdr_accepted_reply(&xdrs, &ar))
{
printf("Failed to encode data.\n");
return 1;
}
xdr_destroy(&xdrs);
// Decode the encoded data.
struct accepted_reply ar2 = {0};
xdrmem_create(&xdrs, buffer, sizeof(buffer), XDR_DECODE);
if (!xdr_accepted_reply(&xdrs, &ar2))
{
printf("Failed to decode data.\n");
return 1;
}
xdr_destroy(&xdrs);
printf("Encoded and decoded data successfully.\n");
return 0;
}
在上面的示例代码中,
- 首先,我们定义了一个长度为
1024
的字符数组buffer
,用于存储编码后的数据;定义枚举变量status
,初始化为RPC_SUCCESS
;定义了一个accepted_reply
结构体,并将其成员变量ar_stat
赋值为status
; - 然后,调用
xdrmem_create()
函数,创建了一个XDR
流对象xdrs
,并将其与buffer
绑定; - 接着,调用
xdr_accepted_reply()
函数将结构体编码为XDR
格式,并将其存储在内存缓冲区buffer
中;编码完成后,调用xdr_destroy()
函数清理流对象xdrs
; - 再然后,定义了结构体
accepted_reply
类型的变量ar2
,并再次调用xdrmem_create()
函数创建了一个新的XDR
流对象xdrs2
,并将其与buffer
绑定 - 最后,我们使用
xdr_accepted_reply()
函数从缓冲区中解码编码后的数据,并将其存储在另一个accepted_reply
结构体ar2
中;解码完成后,调用xdr_destroy()
函数清理流对象xdrs2
。
注意:在调用
xdr_accepted_reply()
时,
- 如果需要编码
accepted_reply
结构体,则应将ar
参数设置为一个已填充的结构体,将XDR_ENCODE
标志传递给xdr_accepted_reply()
函数。该函数将会对结构体进行编码,并在XDR
数据流中存储编码后的结果。- 如果要解码
accepted_reply
结构体,则应将ar
参数设置为一个未初始化的结构体,将XDR_DECODE
标志传递给xdr_accepted_reply()
函数。该函数将会从XDR
数据流中读取数据,并将其解码到ar
结构体中。
2. xdr_array
2.1 函数说明
bool_t xdr_array(XDR *xdrs, char **addrp, u_int *sizep, u_int maxsize, u_int elsize, xdrproc_t elproc);
用于编解码数组类型的数据
参数:
- xdrs : 指向XDR流对象的指针
- addrp : 指向数组地址的指针
- sizep : 指向数组元素个数的指针
- maxsize : 数组的最大容量
- elsize : 每个数组元素的大小
- elproc : 指向编解码数组元素的函数指针
xdr_array()
函数会将数组中的元素按照 elsize
的大小进行编解码,并根据 maxsize
和 sizep
来确定数组的长度。
- 在编码时,
addrp
指向的数组数据会被写入到XDR
流对象xdrs所代表的缓冲区中。 - 在解码时,从
XDR
流对象xdrs
所代表的缓冲区中读取数据,并将其存储到addrp
指向的数组中,同时sizep
会被设置为实际的数组元素个数。
注意: 在使用
xdr_array()
函数编解码数组时,数组的大小必须小于等于maxsize
,并且sizep
必须始终指向数组实际的元素个数。此外,elproc
指向的编解码函数也必须正确地实现对应数据类型的编解码操作。
2.2 演示示例
#include <stdio.h>
#include <rpc/xdr.h>
#define MAX_SIZE 10
int main()
{
int arr[MAX_SIZE] = {1, 2, 3, 4, 5};
int size = 5;
char buffer[1024];
XDR xdrs;
// Encode the array data.
xdrmem_create(&xdrs, buffer, sizeof(buffer), XDR_ENCODE);
if (!xdr_array(&xdrs, (char **)&arr, &size, MAX_SIZE, sizeof(int), (xdrproc_t)xdr_int))
{
printf("Failed to encode data.\n");
return 1;
}
xdr_destroy(&xdrs);
// Decode the encoded data.
xdrmem_create(&xdrs, buffer, sizeof(buffer), XDR_DECODE);
if (!xdr_array(&xdrs, (char **)&arr, &size, MAX_SIZE, sizeof(int), (xdrproc_t)xdr_int))
{
printf("Failed to decode data.\n");
return 1;
}
xdr_destroy(&xdrs);
// Print the decoded array data.
for (int i = 0; i < size; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
在上面的这个示例中,
- 首先,我们定义了一个大小为
MAX_SIZE
的int
类型数组arr
,并初始化其前5
个元素为1、2、3、4 和 5
;定义了int
类型变量size
,并将其赋值为5
,表示数组中实际的元素个数。 - 接着,定义了一个大小为
1024
的字符数组buffer
,并创建一个XDR
流对象xdrs
,并将其与buffer
绑定。 - 然后,调用
xdr_array()
函数,将arr
数组中的数据按照int
类型进行编码,并写入到xdrs
所代表的缓冲区中;编码完成后,调用xdr_destroy()
函数清理流对象xdrs
; - 再接着,创建了一个新的
XDR
流对象xdrs
,并将其与buffer
绑定。 - 再然后,再次调用
xdr_array()
函数,将xdrs
所代表的缓冲区中的数据解码成int
类型的数组并保存到arr
中,同时将实际的数组元素个数存储在size
变量中;解码完成后,调用xdr_destroy()
函数清理流对象xdrs
; - 最后,使用
for
循环遍历arr
数组,并输出其所有元素的值。如果编解码成功,则输出1、2、3、4 和 5
。
3. xdr_authunix_parms
3.1 函数说明
bool_t xdr_authunix_parms(XDR *xdrs, struct authunix_parms *objp);
用于编解码Unix身份验证信息
参数:
- xdrs : 指向
XDR
流对象的指针- objp : 指向
authunix_parms
结构体的指针
关于 xdr_authunix_parms()
函数,
- 在编码时,
xdr_authunix_parms()
函数会将authunix_parms
结构体中的cred
和verf
字段按照规定的格式进行编码,并将编码后的数据写入到XDR
流对象xdrs
所代表的缓冲区中。 - 在解码时,
xdr_authunix_parms()
函数会从XDR
流对象xdrs
所代表的缓冲区中读取数据,并将其存储到authunix_parms
结构体中。
3.2 演示示例
#include <stdio.h>
#include <rpc/xdr.h>
int main()
{
char buffer[1024];
XDR xdrs;
struct authunix_parms auth = {1234, 5678, NULL, 0};
// Encode the auth data.
xdrmem_create(&xdrs, buffer, sizeof(buffer), XDR_ENCODE);
if (!xdr_authunix_parms(&xdrs, &auth))
{
printf("Failed to encode data.\n");
return 1;
}
xdr_destroy(&xdrs);
// Decode the encoded data.
xdrmem_create(&xdrs, buffer, sizeof(buffer), XDR_DECODE);
struct authunix_parms auth2 = {0};
if (!xdr_authunix_parms(&xdrs, &auth2))
{
printf("Failed to decode data.\n");
return 1;
}
xdr_destroy(&xdrs);
// Print the decoded auth data.
printf("uid: %d\ngid: %d\n", auth2.aup_uid, auth2.aup_gid);
for (int i = 0; i < auth2.aup_len; i++)
{
printf("gid[%d]: %d\n", i, auth2.aup_gids[i]);
}
return 0;
}
在上面的示例代码中,
- 首先,我们定义了一个大小为
1024
的字符数组buffer
,并创建一个XDR
流对象xdrs
,并将其与buffer
绑定; - 接着,定义了一个
authunix_parms
结构体变量auth
,并初始化了其中的uid
和gid
字段。由于附属组 ID
为空,因此将指向gids
数组的指针设置为NULL
,aup_len
字段设置为0
; - 然后,调用
xdr_authunix_parms()
函数,将auth
结构体中的数据按照规定的格式进行编码,并写入到xdrs
所代表的缓冲区中;编码完成后,调用xdr_destroy()
函数清理流对象xdrs
; - 再接着,创建一个新的
XDR
流对象xdrs
,并将其与buffer
绑定; - 再然后,再次调用
xdr_authunix_parms()
函数,将xdrs
所代表的缓冲区中的数据解码成authunix_parms
结构体并保存到auth2
中;解码完成后,调用xdr_destroy()
函数清理流对象xdrs
; - 最后,使用
printf
函数输出auth2
中的uid
、gid
和附属组ID
等信息。
4. xdr_bool
4.1 函数说明
bool_t xdr_bool(XDR *xdrs, bool_t *bp);
用于编解码布尔类型的数据
参数:
- xdrs : 指向XDR流对象的指针
- bp : 指向bool_t类型变量的指针,表示要编解码的布尔值
4.2 演示示例
#include <stdio.h>
#include <rpc/xdr.h>
int main()
{
// 创建 XDR 流
XDR xdr;
xdrmem_create(&xdr, NULL, 0, XDR_ENCODE);
// 写入布尔值
bool b = true;
if (!xdr_bool(&xdr, &b))
{
printf("写入失败");
return 1;
}
// 重置 XDR 流为解码模式
xdrrec_endofrecord(&xdr, true);
// 从流中读取布尔值
bool result;
if (!xdr_bool(&xdr, &result))
{
printf("读取失败");
return 1;
}
// 输出结果
printf("读取结果:%d\n", result);
return 0;
}
在上面的这个示例程序中,
- 首先,我们调用
xdrmem_create()
函数创建了一个XDR
流; - 然后,使用
xdr_bool()
函数将true
布尔值写入流中; - 接着,调用
xdrrec_endofrecord()
函数将流重置为解码模式; - 再接着,使用
xdr_bool()
函数从流中读取布尔值; - 最后,调用
printf()
函数输出从流中读取的布尔值。
5. xdr_bytes
5.1 函数说明
bool_t xdr_bytes(XDR *xdrs, char **cpp, u_int *sizep, u_int maxsize);
用于 XDR(外部数据表示)编程的数据类型,它可以将任意二进制数据转换为字节数组,并在 XDR 流中进行传输
参数:
- xdrs : 指向要编码或解码数据的 XDR 结构体的指针
- cpp : 指向将要编码或解码的数据的字符指针的指针。在编码时,cpp 是一个输入参数,指向要编码的数据;在解码时,cpp 是一个输出参数,指向存储已解码数据的缓冲区
- sizep : 指向将要编码或解码的数据大小的无符号整数指针。在编码时,sizep 是一个输入参数,指示要编码的数据大小;在解码时,sizep 是一个输出参数,指示已解码数据的大小。
- maxsize : 指定数据的最大大小。如果实际大小超过此值,则会发生错误
在计算机网络和分布式系统中,XDR
通常用于在不同的计算机之间传递数据。可以实现如下的功能:
- 将任意二进制数据转换为字节数组:
xdr_bytes()
函数可以将一个二进制数据块转换为字节数组。这个数据块可以是任何类型的数据,例如整数、字符串、结构体等。 - 在
XDR
流中进行传输:它可以将转换后的字节数组写入 XDR 流中,以便在不同的计算机之间进行传输。在传输过程中,字节数组会被打包到 XDR 数据包中,并添加一些元数据来描述数据的类型和长度等信息。 - 从
XDR
流中读取字节数组:它还可以从XDR
流中读取字节数组,并将其转换回原始的二进制数据块。这个过程与写入过程相反,即从XDR
数据包中解包出字节数组,并将其转换为原始的数据类型。
5.2 演示示例
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <rpc/xdr.h>
int main()
{
// 创建 XDR 流
XDR xdr;
xdrmem_create(&xdr, NULL, 0, XDR_ENCODE);
// 写入字节数组
char* data = "Hello, world!";
int length = strlen(data);
if (!xdr_bytes(&xdr, (char **)&data, &length, 100))
{
printf("写入失败");
return 1;
}
// 重置 XDR 流为解码模式
xdrrec_endofrecord(&xdr, true);
// 从流中读取字节数组
char* result = NULL;
int result_length;
if (!xdr_bytes(&xdr, (char **)&result, &result_length, 100))
{
printf("读取失败");
return 1;
}
// 输出结果
printf("读取结果:%s\n", result);
// 释放内存
free(result);
return 0;
}
知识拓展
XDR(External Data Representation)
是一种用于表示数据的格式,它独立于特定的计算机体系结构和编程语言。XDR
最初由 Sun
公司开发,旨在解决分布式系统中不同计算机之间通信的问题,它可以将数据从一台计算机转换为另一台计算机可以理解的格式。
XDR
定义了一组规则和约定,用于将常见数据类型(例如整数、浮点数、字符串等)以及自定义数据类型(例如结构体、联合体等)转换为一个统一的二进制格式,并在网络上传输。
这个二进制格式具有以下特点:
- 独立于任何特定的计算机体系结构和编程语言;
- 严格定义了数据类型的大小和对齐方式;
- 可以通过标准的网络协议进行传输
使用 XDR
,不同计算机之间可以轻松地共享数据,而无需考虑它们的硬件平台或编程语言。因此,XDR
在许多分布式系统中得到广泛应用,例如 RPC
(远程过程调用)、NFS
(网络文件系统)等。
当然,在实际的应用中,XDR
已经被其他更先进的技术所取代,例如 XML
、JSON
等。但是,作为一种经典的数据表示格式,XDR
仍然具有一定的历史地位和实用价值。
参考资料
- [XDR: External Data Representation Standard]