首页 > 其他分享 >C语言函数大全-- x 开头的函数(3)

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

时间:2023-05-23 23:01:10浏览次数:38  
标签:编码 函数 -- 解码 C语言 xdrs XDR printf xdr

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 :表示消息类型,可以是 CALLREPLY
  • 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 对象中读取编码数据。如果解码成功,则打印出解码后的消息。
  • 最后,程序正常退出。

标签:编码,函数,--,解码,C语言,xdrs,XDR,printf,xdr
From: https://blog.51cto.com/huazie/6335278

相关文章

  • PowerShell系列(二):PowerShell和Python之间的差异介绍
    今天给大家聊聊PowerShell和Python之间有哪些共同之处,各自有哪些优势,希望对运维的朋友了解两种语言能提供一些有用的信息。1、  Python定义Python是一种面向对象的解释型计算机程序设计语言,由荷兰人GuidovanRossum于1989年发明,第一个公开发行版发行于1991年。Python是纯粹的自......
  • 入门指南:学习C++编程的关键步骤
    C++是一种功能强大的编程语言,广泛应用于软件开发和系统编程。如果您想学习C++编程,下面是一些关键的步骤,可以帮助您入门。安装C++编译器要开始学习C++,您需要安装一个C++编译器。常用的C++编译器有GCC、Clang和MicrosoftVisualC++等。您可以根据自己的操作系统选择适合的编译器,并......
  • webpack-了解devServer中常用的选项
    devServer节点在webpack.config.js配置文件中,可以通过devServer节点对webpack-dev-server插件进行更多的配置,示例代码如下:devServer:{ open:ture,//初次打包完成后,自动打开浏览器 host:'127.0.0.1',//实时打包所使用的主机地址 port:80,//实时打包所使用的端口号}注意:凡是......
  • [鲜花] #1 About Me
    也算是第一篇鲜花?不知道为什么,才初中就把自己弄得很累,可能周围的人都很卷吧(雾md数学初中平几什么玩意,乱搞出奇迹的玄学玩意现在是whk&OI散修寄寄人我们OIer最擅长的就是把压力转换为动力,毕竟经历了连续两年CSPJ遗憾离场,我还有什么比这段经历更难受的呢?现在证明了自己,继续往......
  • [hc32f460填坑] SystemCoreClock在进入main后变为0
    我的芯片型号是hc32f460jeua,使用的库为HC32F460_DDL_Rev3.1.0,keil包为HDSC.HC32F460.1.0.10。发现的问题:执行完SystemInit后SystemCoreClock为200000000,一进入mian函数就变为零。原因:__NO_INIT未起作用,__main对SystemCoreClock进行了初始化解决方法:1.把这两个勾上2,将Zero......
  • 回文数
    一、问题描述打印所有不超过n(取n<256)的其平方具有对称性质的数(也称回文数)。二、设计思路对于要判定的数n,计算出其平方后(存于a),按照“回文数”的定义要将最高位与最低位、次高位与次低位······进行比较,若彼此相等则为回文数。此算法需要知道平方数的位数,再一一将每一......
  • [ABC143E] Travel by Car
    TravelbyCar的传送门\(n\le300\)可凭感觉进行一遍Floyd。然后选两个点\(i,j\),如果\(i,j\)间的距离小于等于\(l\),则将\(i,j\)连一条代价为\(1\)的边(假设\(i,j\)要用一桶油)。最后再来一遍Floyd即可。因为第一次是加满油的,所以答案要\(-1\)。#include<bit......
  • Python实验课4
    实验一实验源码1print(sum)2sum=423print(sum)45definc(n):6sum=n+17print(sum)8returnsum910sum=inc(7)+inc(7)11print(sum)实验截图实验二task2.1Python实验源码1deffunc1(a,b,c,d,e,f):2return[a,......
  • 插入排序
    参考实现'''插入排序初始是一个有序列表,每次从无序列表取一个元素放到合适的位置完成排序'''definsert_sort(list):foriinrange(1,len(list)):#此时i表示无序元素的索引temp=list[i]#新来的待排序元素j=i-1#有序元素......
  • IDEA配置jdk(或者IDEA代码报错The SDK is not specified for module)
    参考:https://blog.csdn.net/mask_boys/article/details/117385087今天敲代码时,出现一个错误,那就是TheSDKisnotspecifiedfor module,意思是没有为模块添加SDK,所以会出现如下错误 如何解决这个问题呢:首先:file-》projectStructure 然后 点击下划选项,然后就可以添加......