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:
- 修改你的
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; // 这个就是带判别式的那个类型 };
- 调用
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
相关产品推荐
相关产品推荐

