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]
