【发布时间】:2015-02-12 03:45:33
【问题描述】:
使用libtirpc 库通过 RPC 发送数组有点困难。在客户端-服务器会话期间发送原语很简单:
// Client-side boilerplate
struct timeval tout = { 1, 0 };
int in = 42;
clnt_call (cln, 1, (xdrproc_t)xdr_int, (char*)&in,
(xdrproc_t)xdr_void, NULL, tout);
// Server-side boilerplate
int in;
svc_getargs (xprt, (xdrproc_t)xdr_int, (char*)&in);
assert (in == 42);
xdrproc_t 函数签名是bool_t (*xdrproc_t) (XDR *, void *, ...);。 xdr_int(3)、xdr_long(3) 和其他原始序列化程序没有可变参数,因此可以直接使用 clnt_call(3) 和 svc_getargs(3) 函数使用它们。然而,用于序列化可变长度数组的 xdr_array(3) 函数需要更多参数:
bool_t xdr_array(XDR *xdrs, char **arrp, unsigned int *sizep,
unsigned int maxsize, unsigned int elsize,
xdrproc_t elproc);
clnt_call(3) 和 svc_getargs(3) 函数不能真正将这些参数传递给函数,因此创建包装函数似乎是解决问题的最干净的解决方案:
// Client-side boilerplate
long a = 1, b = 2;
long * arr[] = { &a, &b };
unsigned int amount = sizeof(arr) / sizeof(long*);
bool_t xdr_array_wrapper (XDR * xdr, void * ptr) {
return xdr_array (xdr, ptr, &amount, amount,
sizeof(long), (xdrproc_t)xdr_long);
}
struct timeval tout = { 1, 0 };
long out;
clnt_call (cln, 1, (xdrproc_t)xdr_array_wrapper,
(char*)arr, (xdrproc_t)xdr_long, (char*)&out, tout);
// Server-side boilerplate
long * arr[2];
unsigned int amount = sizeof(arr) / sizeof(long*);
bool_t xdr_array_wrapper (XDR * xdr, void * ptr) {
return xdr_array (xdr, ptr, &amount, amount,
sizeof(long), (xdrproc_t)xdr_long);
}
svc_getargs (xprt, (xdrproc_t)xdr_array_wrapper, (char*)arr);
long a = *arr[0], b = *arr[1];
但是,由于某些未知原因,只有数组的第一个元素(变量a)被传输,而另一个包含垃圾。我做错了什么?
【问题讨论】: