You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

XDR union赋值至结构体union时类型不兼容错误求助

解决RPC中XDR Union赋值的类型不兼容问题

看起来你在RPC服务端处理参数的时候踩了XDR union的常见坑——XDR生成的union和普通C union根本不是一回事!我来帮你拆解问题,一步步解决:

问题根源:XDR Union是带判别式的结构体,不是裸C Union

用rpcgen生成的XDR union,本质是一个包含判别式(tag)和实际union的结构体,而不是你代码里写的那种裸union。举个例子,假设你的.x服务定义里有这样的union:

union get_minified_image_arg switch (ImageReqType) {
    case MINIFY_REQ: inputImage img_data;
    // 其他请求类型分支
};

rpcgen会生成类似这样的C类型:

typedef enum { MINIFY_REQ = 0 /* 其他枚举值 */ } ImageReqType;

typedef struct {
    ImageReqType discriminant; // 判别式,标记当前union用哪个分支
    union {
        inputImage img_data;
        // 其他分支类型
    } choice; // 实际的union内容
} get_minified_image_arg;

而你在struct data_str里定义的是裸union:

struct data_str {
    // ... 其他字段
    union {
        inputImage get_minified_...
        // 其他成员
    };
};

这俩类型完全不匹配,直接赋值或memcpy自然会报类型错误!

解决方案

方案1:直接使用RPC生成的Union结构体类型

最简单的办法是让data_str里的字段直接用rpcgen生成的带判别式的结构体类型,而不是自己定义裸union:

  1. 修改你的data_str定义:
struct data_str {
    struct svc_req *rqstp;
    SVCXPRT *transp;
    bool_t retval;
    xdrproc_t _xdr_result;
    // 直接用rpcgen生成的union结构体类型
    get_minified_image_1_arg req_arg; // 这个就是带判别式的那个类型
};
  1. 调用svc_getargs时直接传这个字段的地址:
struct data_str my_data;
my_data.rqstp = rqstp; // 假设你拿到了svc_req指针

// 解析参数到data_str的req_arg字段
if (!svc_getargs(my_data.rqstp, (xdrproc_t)xdr_get_minified_image_1_arg, &my_data.req_arg)) {
    svcerr_decode(my_data.rqstp);
    return;
}

// 之后可以直接通过判别式访问内容
if (my_data.req_arg.discriminant == MINIFY_REQ) {
    inputImage img = my_data.req_arg.choice.img_data;
    // 处理图像逻辑
}

方案2:手动分支复制到裸Union(不推荐,但如果必须用的话)

如果你一定要把内容放到自己定义的裸union里,必须先根据判别式判断分支,再逐个成员赋值,不能直接memcpy:

// 假设rpcgen生成的union类型是get_minified_image_1_arg
get_minified_image_1_arg rpc_arg;
struct data_str my_data;

// 先解析到rpc生成的union结构体
if (!svc_getargs(rqstp, (xdrproc_t)xdr_get_minified_image_1_arg, &rpc_arg)) {
    svcerr_decode(rqstp);
    return;
}

// 根据判别式分支赋值到裸union
switch(rpc_arg.discriminant) {
    case MINIFY_REQ:
        my_data.my_union.get_minified = rpc_arg.choice.get_minified_image_arg;
        break;
    // 其他分支同理
    case OTHER_REQ:
        my_data.my_union.other_field = rpc_arg.choice.other_arg;
        break;
    default:
        // 处理无效请求类型
        svcerr_systemerr(rqstp);
        return;
}

为什么memcpy不行?

因为RPC生成的union结构体比你的裸union多了一个判别式字段(枚举值),直接memcpy会把这个额外的字节/字节数复制到你的裸union里,不仅类型不匹配,还会破坏内存布局,导致未定义行为。

内容的提问来源于stack exchange,提问作者legendofawesomeness

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:46:15