当前位置 : 主页 > 编程语言 > c语言 >

C语言函数大全-- x 开头的函数(1)

来源:互联网 收集:自由互联 发布时间:2023-09-03
C语言函数大全 本篇介绍C语言函数大全-- x 开头的函数 1. xdr_accepted_reply 1.1 函数说明 函数声明 函数功能 bool_t xdr_accepted_reply(XDR *xdrs, struct accepted_reply *ar); 用于将 RPC (远程过程调用)应

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 的大小进行编解码,并根据 maxsizesizep 来确定数组的长度。

  • 在编码时,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_SIZEint 类型数组 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 结构体中的 credverf 字段按照规定的格式进行编码,并将编码后的数据写入到 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,并初始化了其中的 uidgid 字段。由于 附属组 ID 为空,因此将指向 gids 数组的指针设置为 NULLaup_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 中的 uidgid附属组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 已经被其他更先进的技术所取代,例如 XMLJSON 等。但是,作为一种经典的数据表示格式,XDR 仍然具有一定的历史地位和实用价值。

参考资料

  1. [XDR: External Data Representation Standard]
上一篇:递归与迭代
下一篇:没有了
网友评论