C语言函数大全
本篇介绍C语言函数大全-- x 开头的函数
1. xdr_opaque
1.1 函数说明
bool_t xdr_opaque(XDR *xdrs, char *buf, u_int len);
用于编码或解码任意长度的二进制数据
参数:
- xdrs : 指向
XDR
数据结构的指针,表示要进行编码或解码的数据流- buf : 指向待编码或解码的二进制数据的指针
- len : 待编码或解码的二进制数据的长度(以字节为单位)
返回值:
- 如果编码或解码成功,则返回值为
TRUE
;- 否则返回值为
FALSE
。
1.2 演示示例
#include <stdio.h>
#include <stdlib.h>
#include <rpc/xdr.h>
int main()
{
// 编码数据
char data[] = "hello, world!";
XDR xdr;
xdrmem_create(&xdr, NULL, 0, XDR_ENCODE);
if (!xdr_opaque(&xdr, data, sizeof(data)))
{
printf("Error: failed to encode data.\n");
exit(EXIT_FAILURE);
}
// 获取编码后的数据并打印
char *encoded_data = malloc(xdr_getpos(&xdr));
xdrmem_create(&xdr, encoded_data, xdr_getpos(&xdr), XDR_DECODE);
printf("Encoded data: ");
for (int i = 0; i < xdr_getpos(&xdr); ++i)
{
printf("%02x ", encoded_data[i]);
}
printf("\n");
// 解码数据
char decoded_data[sizeof(data)];
if (!xdr_opaque(&xdr, decoded_data, sizeof(decoded_data)))
{
printf("Error: failed to decode data.\n");
exit(EXIT_FAILURE);
}
printf("Decoded data: %s\n", decoded_data);
return 0;
}
在上面的示例代码中,
- 首先,我们定义了一个字符串
"hello, world!"
作为将要编码的数据,并创建了一个XDR
结构体; - 然后,调用
xdrmem_create()
函数初始化XDR
结构体,使其可以从内存中读取和写入数据; - 接着,使用
xdr_opaque()
函数对字符串进行编码,将其转换为 XDR 格式; - 再然后,获取编码后的数据并打印;其中,
- 我们先使用
xdr_getpos()
函数获取已编码数据的长度; - 然后再使用
xdrmem_create()
函数创建一个新的XDR
结构体来解码它; - 最后,利用循环遍历编码后的数据并以十六进制形式打印出来。
- 我们先使用
- 再接着,使用
xdr_opaque()
函数对编码后的数据进行解码; - 最后,打印解码后的数据。
2. xdr_opaque_auth
2.1 函数说明
bool_t xdr_opaque_auth(XDR *xdrs, struct opaque_auth *ap);
用于编码或解码 认证信息
参数:
- xdrs : 指向
XDR
结构体的指针,用于指定编解码的上下文- ap : 指向
opaque_auth
结构体的指针,用于指定认证信息
返回值:
- 如果编码或解码成功,则返回值为
TRUE
;- 否则返回值为
FALSE
。
2.2 演示示例
2.2.1 opaque_auth
// 定义在 <rpc/auth.h>
struct opaque_auth {
int oa_flavor; // 认证方式(authentication flavor)
caddr_t oa_base; // 不透明数据
u_int oa_length; // 数据长度
};
2.2.2 test.c
#include <stdio.h>
#include <stdlib.h>
#include <rpc/xdr.h>
#include <rpc/auth.h>
int main()
{
// 编码数据
struct opaque_auth auth;
auth.oa_flavor = AUTH_NONE;
auth.oa_base = NULL;
auth.oa_length = 0;
XDR xdr;
xdrmem_create(&xdr, NULL, 0, XDR_ENCODE);
if (!xdr_opaque_auth(&xdr, &auth))
{
printf("Error: failed to encode authentication information.\n");
exit(EXIT_FAILURE);
}
// 获取编码后的数据并打印
char *encoded_data = malloc(xdr_getpos(&xdr));
xdrmem_create(&xdr, encoded_data, xdr_getpos(&xdr), XDR_DECODE);
printf("Encoded data: ");
for (int i = 0; i < xdr_getpos(&xdr); ++i)
{
printf("%02x ", encoded_data[i]);
}
printf("\n");
// 解码认证信息
struct opaque_auth decoded_auth;
xdrmem_create(&xdr, encoded_data, xdr_getpos(&xdr), XDR_DECODE);
if (!xdr_opaque_auth(&xdr, &decoded_auth))
{
printf("Error: failed to decode authentication information.\n");
exit(EXIT_FAILURE);
}
// 打印解码后的认证信息
printf("Decoded authentication information:\n");
printf("oa_flavor = %d\n", decoded_auth.oa_flavor);
printf("oa_length = %u\n", decoded_auth.oa_length);
return 0;
}
在上面的这个示例中,
- 首先,我们创建一个
opaque_auth
结构体,并将其中的成员变量初始化。
注意: 由于使用的认证方式是
AUTH_NONE
,也就是不需要任何认证信息;所以,oa_length
成员变量被设置为0
。在实际开发中,我们可能需要使用其他的认证方式,并相应地设置opaque_auth
结构体的成员变量。】
-
然后,使用
xdrmem_create()
函数创建一个XDR
结构体,并将其指定为编码模式。 -
接着,调用
xdr_opaque_auth()
函数对认证信息进行编码,并获取编码后的数据并打印出来【这里同 1.2 中,不再赘述】。 -
再然后,使用
xdrmem_create()
函数创建一个新的XDR
结构体,并将其指定为解码模式。 -
再接着,调用
xdr_opaque_auth()
函数对编码后的认证信息进行解码,并通过访问opaque_auth
结构体的成员变量来获取解码后的认证信息。 -
最后,打印解码后的认证信息。
3. xdr_pointer
3.1 函数说明
bool_t xdr_pointer(XDR *xdrs, char **objpp, u_int obj_size, xdrproc_t xdr_obj)
用于编码和解码指针类型的数据
参数:
- xdrs : 指向要编码或解码数据的
XDR
结构体的指针- objpp : 要编码或解码的数据的地址
- obj_size : 要编码或解码的数据的大小(以字节为单位)
- xdr_obj : 用于编码或解码指针所指向的数据
返回值:
- 如果编码或解码成功,则返回值为
TRUE
;- 否则返回值为
FALSE
。
关于 xdr_pointer()
函数的使用,参考如下:
-
对于编码操作,
xdr_pointer()
函数将指针objpp
所指向的数据编码到XDR
流中。如果objpp
为 NULL,则写入一个特殊的标志来表示空指针。如果objpp
不为NULL
,则先写入一个非零值来表示非空指针,然后调用指定的XDR
编码程序对数据进行编码。 -
对于解码操作,
xdr_pointer()
函数从XDR
流中读取一些字节,并根据这些字节创建一个新的数据对象。如果读取的字节表示一个空指针,则将objpp
设置为NULL
。否则,将objpp
设置为一个指向新对象的指针,并调用指定的XDR
编码程序对数据进行解码。
3.2 演示示例
#include <stdio.h>
#include <rpc/xdr.h>
int main()
{
char buffer[1024];
XDR xdrs;
xdrmem_create(&xdr, buffer, sizeof(buffer), XDR_ENCODE); // 创建 XDR 流
// 将指针编码为 XDR 流中的整数
int pointer_value = 42;
xdr_pointer(&xdrs, (char **)&pointer_value, sizeof(int), (xdrproc_t)xdr_int);
// 打印编码后的值
printf("Encoded value: %d\n", pointer_value);
// 解码整数,还原指针
xdr_setpos(&xdrs, 0);
xdr_pointer(&xdrs, (char **)&pointer_value, sizeof(int), (xdrproc_t)xdr_int);
// 打印解码后的指针值
printf("Decoded value: %d\n", pointer_value);
// 关闭流
xdr_destroy(&xdrs);
return 0;
}
在上面的示例代码中,
- 首先,我们创建了一个
XDR
流对象xdrs
,并将其绑定到buffer
数组上; - 然后,使用
xdr_pointer()
函数将 整数指针pointer_value
写入流中;并输出pointer_value
的值,这是编码后的整数; - 再接着,使用
xdr_setpos()
函数将XDR
流的位置设置为0
; - 再然后,使用
xdr_pointer()
函数从XDR
流中解码整数值,并将其存储回pointer_value
变量中;并输出pointer_value
的值,这是解码后的整数指针; - 最后,使用
xdr_destroy()
函数关闭并释放XDR
流对象,并结束程序。
4. xdr_replymsg
4.1 函数说明
bool_t xdr_replymsg(XDR *xdrs, struct rpc_msg *msg);
用于编码或解码应答消息
参数:
- xdrs : 指向要编码或解码数据的
XDR
结构体的指针- msg : 指向要编码或解码的枚举类型数据的指针
返回值:
- 如果编码或解码成功,则返回值为
TRUE
;- 否则返回值为
FALSE
。
在使用 xdr_replymsg()
函数之前,需要设置好 rpc_msg
结构体中的各个字段。rpc_msg
结构体用于表示 RPC
消息,其中包括以下字段:
uint32_t xid
:表示此消息的标识符。enum msg_type msg_type
:表示消息类型,可以是CALL
或REPLY
。union rpc_body
:表示RPC
的主体部分,包括:call_body
:表示CALL
消息的主体部分,包括RPC
的程序号、版本号和过程号,以及传递给该过程的参数。reply_body
:表示REPLY
消息的主体部分,包括返回值和可能的错误信息。
4.2 演示示例
#include <stdio.h>
#include <stdlib.h>
#include <rpc/xdr.h>
int main()
{
// 创建 XDR 流对象
char buffer[1024];
XDR xdrs;
xdrmem_create(&xdrs, buffer, sizeof(buffer), XDR_ENCODE);
// 设置 rpc_msg 结构体
struct rpc_msg msg = {.xid = 12345, .msg_type = REPLY};
msg.acpted_rply.ar_verf = AUTH_NULL;
msg.acpted_rply.ar_results.where = (char *)"Success";
msg.acpted_rply.ar_results.proc = (xdrproc_t)xdr_string;
// 编码应答消息
if (!xdr_replymsg(&xdrs, &msg))
{
fprintf(stderr, "Failed to encode reply message\n");
return 1;
}
// 打印编码后的结果
printf("Encoded message: ");
for (int i = 0; i < xdr_getpos(&xdrs); i++)
{
printf("%02x", buffer[i] & 0xff);
}
printf("\n");
// 解码应答消息
struct rpc_msg decoded_msg;
if (!xdr_replymsg(&xdrs, &decoded_msg))
{
fprintf(stderr, "Failed to decode reply message\n");
return 1;
}
// 打印解码后的结果
printf("Decoded message:\n");
printf("XID: %d\n", decoded_msg.xid);
printf("Message Type: %d\n", decoded_msg.msg_type);
printf("Verf Flavor: %d\n", decoded_msg.acpted_rply.ar_verf.oa_flavor);
printf("Verf Length: %d\n", decoded_msg.acpted_rply.ar_verf.oa_length);
printf("Result:\n");
char *result;
if (!xdr_string(&xdrs, &result, sizeof(result)))
{
fprintf(stderr, "Failed to decode result string\n");
return 1;
}
printf("%s\n", result);
return 0;
}
在上面的这个示例程序中,
- 首先,创建一个
XDR
流对象,并设置一个包含所需信息的rpc_msg
结构体。 - 接着,使用
xdr_replymsg()
函数将rpc_msg
结构体编码为XDR
格式。如果编码失败,则输出错误并退出程序。 - 然后,打印编码后的结果,以便查看序列化的数据。
- 再接着,使用
xdr_replymsg()
函数将编码后的数据解码回rpc_msg
结构体。如果解码失败,则输出错误并退出程序。 - 再然后,打印解码后的结果,包括事务
ID
、消息类型、验证标志、结果等信息; - 最后,程序正常退出。
5. xdr_reference
5.1 函数说明
bool_t xdr_reference(XDR *xdrs, char **objp, u_int obj_size, xdrproc_t xdr_func);
用于编码或解码一个指向某个对象的引用
参数:
- xdrs : 指向要编码或解码数据的
XDR
结构体的指针- objp : 指向要编码或解码的某个指针对象的引用
- obj_size : 引用的指针对象的大小
- xdr_func : 指向 XDR 函数的指针,用于编码或解码 objp 所指向的数据对象
返回值:
- 如果编码或解码成功,则返回值为
TRUE
;- 否则返回值为
FALSE
。
5.2 演示示例
#include <stdio.h>
#include <stdlib.h>
#include <rpc/xdr.h>
int main()
{
// 创建 XDR 流对象
char buffer[1024];
XDR xdrs;
xdrmem_create(&xdrs, buffer, sizeof(buffer), XDR_ENCODE);
// 设置字符串指针
char *str = "Hello, world!";
// 编码字符串指针
if (!xdr_reference(&xdrs, &str, strlen(str) + 1, (xdrproc_t)xdr_string))
{
fprintf(stderr, "Failed to encode string reference\n");
return EXIT_FAILURE;
}
// 打印编码后的结果
printf("Encoded message: ");
for (int i = 0; i < xdr_getpos(&xdrs); i++)
{
printf("%02x", buffer[i] & 0xff);
}
printf("\n");
// 创建一个新的 XDR 流对象,并反序列化字符串指针
XDR new_xdrs;
xdrmem_create(&new_xdrs, buffer, sizeof(buffer), XDR_DECODE);
char *decoded_str = NULL;
if (!xdr_reference(&new_xdrs, &decoded_str, strlen(str) + 1, (xdrproc_t)xdr_string))
{
fprintf(stderr, "Failed to decode string reference\n");
return EXIT_FAILURE;
}
// 打印解码后的结果
printf("Decoded message: %s\n", decoded_str);
return EXIT_SUCCESS;
}
在上面的示例代码中,
- 首先,我们调用
xdrmem_create()
函数创建了一个XDR
流对象xdrs
,并和buffer
绑定; - 然后,定义了一个字符串指针
str
并初始化为"Hello, world!"
; - 接着,调用
xdr_reference()
函数对str
进行编码,并将结果存储到buffer
中。如果编码成功,则打印出编码后的消息; - 再接着,调用
xdrmem_create()
函数创建了一个新的XDR
流对象new_xdrs
,并和buffer
绑定; - 再然后,调用
xdr_reference()
函数解码decoded_str
,并从new_xdrs
对象中读取编码数据。如果解码成功,则打印出解码后的消息。 - 最后,程序正常退出。
6. xdr_rpc_gss_data
6.1 函数说明
bool_t xdr_rpc_gss_data(XDR * xdrs, rpc_gss_data * gd);
用于编码或解码 RPC GSS 数据
参数:
- xdrs : 指向要编码或解码数据的
XDR
结构体的指针- gd : 指向 rpc_gss_data 结构体的指针
返回值:
- 如果编码或解码成功,则返回值为
TRUE
;- 否则返回值为
FALSE
。
6.2 演示示例
#include <stdio.h>
#include <stdlib.h>
#include <rpc/rpc.h>
#include <rpc/auth_gss.h>
int main()
{
rpc_gss_data gd;
XDR xdr;
char buffer[1024];
bool_t status;
memset(&gd, 0, sizeof(gd));
memset(&xdr, 0, sizeof(xdr));
xdrmem_create(&xdr, buffer, sizeof(buffer), XDR_ENCODE);
status = xdr_rpc_gss_data(&xdr, &gd);
if (!status)
{
fprintf(stderr, "Serialization failed.\n");
exit(1);
}
xdrmem_create(&xdr, buffer, sizeof(buffer), XDR_DECODE);
status = xdr_rpc_gss_data(&xdr, &gd);
if (!status)
{
fprintf(stderr, "Deserialization failed.\n");
exit(1);
}
return 0;
}
7. xdr_rpcb
7.1 函数说明
bool_t xdr_rpcb(XDR *xdrs, struct rpcb *objp);
用于编码和解码 RPCBIND 程序号和版本号,以及程序地址信息
参数:
- xdrs : 指向要编码或解码数据的
XDR
结构体的指针- objp : 指向 rpcb 结构体的指针
返回值:
- 如果编码或解码成功,则返回值为
TRUE
;- 否则返回值为
FALSE
。
7.2 演示示例
// RPCBIND 程序号和版本号,以及程序地址
struct rpcb {
char *r_progname;
u_long r_progvers;
struct netbuf r_addr;
char *r_netid;
};
// 网络地址信息
struct netbuf {
u_int maxlen;
u_int len;
char *buf;
};
#include <stdio.h>
#include <rpc/rpc.h>
int main()
{
struct rpcb rpcb_obj = {"my_program", 1, {0, 0, NULL}, "tcp"};
XDR xdr;
char buffer[1024];
xdrmem_create(&xdr, buffer, sizeof(buffer), XDR_ENCODE);
if (xdr_rpcb(&xdr, &rpcb_obj))
{
printf("Serialization success!\n");
}
else
{
printf("Serialization failed!\n");
}
return 0;
}
8. xdr_short
8.1 函数说明
bool_t xdr_short(XDR *xdrs, short *sp);
用于编码或解码短整型数据
参数: 参数:
- xdrs : 指向要编码或解码数据的
XDR
结构体的指针- sp : 指向要编码或解码的
short
类型数据的指针
返回值:
- 如果编码或解码成功,则返回值为
TRUE
;- 否则返回值为
FALSE
。
8.2 演示示例
#include <rpc/xdr.h>
#include <stdio.h>
int main()
{
XDR xdr;
char buf[256];
short num = 42;
// 初始化 XDR 流结构体
xdrmem_create(&xdr, buf, sizeof(buf), XDR_ENCODE);
// 编组 short 类型变量
if (!xdr_short(&xdr, &num))
{
fprintf(stderr, "编组失败!\n");
return 1;
}
// 重置流位置
xdr_setpos(&xdr, 0);
// 解组 short 类型变量
short decoded_num;
if (!xdr_short(&xdr, &decoded_num))
{
fprintf(stderr, "解组失败!\n");
return 1;
}
printf("编组的值:%d,解组的值:%d\n", num, decoded_num);
return 0;
}
9. xdr_string
9.1 函数说明
bool_t xdr_string(XDR *xdrs, char **cpp, u_int maxsize);
用于编码或解码字符串数据
参数:
- xdrs : 指向要编码或解码数据的
XDR
结构体的指针- cpp : 指向要编码或解码的字符串数据的指针
- maxsize : 最大允许的字符串长度
返回值:
- 如果编码或解码成功,则返回值为
TRUE
;- 否则返回值为
FALSE
。
9.2 演示示例
#include <stdio.h>
#include <rpc/xdr.h>
int main()
{
char *str = "hello world!";
char buf[1024];
XDR xdrs;
xdrmem_create(&xdrs, buf, sizeof(buf), XDR_ENCODE);
if (!xdr_string(&xdrs, &str, strlen(str)))
{
printf("Serialization failed.\n");
}
else
{
printf("Serialized data:\n");
for (int i = 0; i < xdr_getpos(&xdrs); i++)
{
printf("%02x ", buf[i]);
}
printf("\n");
}
return 0;
}
10. xdr_string_ptr
10.1 函数说明
bool_t xdr_string_ptr(XDR *xdrs, char **cpp, const uint_t maxsize);
用于编码或解码指向字符串的指针
参数:
- xdrs : 指向要编码或解码数据的
XDR
结构体的指针- cpp : 指向要编码或解码的字符串数据的指针
- maxsize : 最大允许的字符串长度
返回值:
- 如果编码或解码成功,则返回值为
TRUE
;- 否则返回值为
FALSE
。
10.2 演示示例
#include <stdio.h>
#include <rpc/xdr.h>
int main()
{
char str[50] = "Hello, world!";
XDR xdrs;
xdrmem_create(&xdrs, str, sizeof(str), XDR_ENCODE);
xdr_string_ptr(&xdrs, &str, sizeof(str));
printf("Encoded string: %s\n", str);
char decoded_str[50];
xdrmem_create(&xdrs, str, sizeof(str), XDR_DECODE);
xdr_string_ptr(&xdrs, &decoded_str, sizeof(decoded_str));
printf("Decoded string: %s\n", decoded_str);
return 0;
}