使用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
)而另一个元素包含垃圾。我做错了什么?
答案 0 :(得分:2)
您错误地使用xdr_array
有两个原因。
int*
数组,就好像它是一个int
数组一样。使用它的正确方法是这样的(从IBM偷来并简化,请参考链接以获得更完整的处理方法):
typedef struct xarray
{
int size;
int *p_array;
} xarray ;
bool_t xdr_xarray(XDR *xdrs, xarray *p_xarray )
{
return xdr_array(
xdrs,
(char**)(&(p_xarray->p_array)),
&(p_xarray->size),
MAX_INT,
sizeof(int),
(xdrproc_t)xdr_int))
}
请注意这些问题:
p_array
是指向动态分配数组的指针。int
的数组,而不是指针。p_array
的地址传递给xdr_array
,以便在解码时可以分配所需大小的数组并将其分配给p_array
。如果您需要固定大小的数组,则需要使用xdr_vector
。
typedef struct xvector
{
int vector[42];
} xarray ;
bool_t xdr_xvector(XDR *xdrs, xarray *p_xvector )
{
return xdr_vector(
xdrs,
(char*)p_xvector->vector,
42,
sizeof(int),
(xdrproc_t)xdr_int))
}
注意你仍然不应该在这里使用指针数组。
RPC编译器会自动从您的数据结构生成XDR过程,因此请考虑使用一个。