为什么我的节俭型(c_glib)客户会以“失败”而失败;无效指针";错误
我正在用C(g_lib)创建一个简单的thrift服务器/客户端程序。 这是我的节俭IDL文件的外观:为什么我的节俭型(c_glib)客户会以“失败”而失败;无效指针";错误,c,thrift,glib,C,Thrift,Glib,我正在用C(g_lib)创建一个简单的thrift服务器/客户端程序。 这是我的节俭IDL文件的外观: namespace cpp tutorial service Calculator { void ping(), binary getdata() } thrift服务器上getdata的实现如下所示: static gboolean tutorial_calculator_handler_getdata (CalculatorIf *iface,
namespace cpp tutorial
service Calculator {
void ping(),
binary getdata()
}
thrift服务器上getdata的实现如下所示:
static gboolean
tutorial_calculator_handler_getdata (CalculatorIf *iface,
GByteArray *_return,
GError **error)
{
THRIFT_UNUSED_VAR (iface);
THRIFT_UNUSED_VAR (error);
puts ("getdata()");
GByteArray *gbarray;
gint i;
gbarray = g_byte_array_new ();
for (i = 0; i < 100; i++)
g_byte_array_append (gbarray, (guint8*) &i, 1);
*_return = *gbarray;
return TRUE;
}
不幸的是,客户端在calculator\u if\u getdata调用中崩溃,并显示以下消息:
*** Error in `./client': munmap_chunk(): invalid pointer: 0xb741742d ***
Aborted (core dumped)
这是以节约的方式将整数数组从服务器发送到客户端的正确方法吗?我在这里做错了什么?我看到你在这里做的有三个问题:
- 如果服务方法返回复杂类型,则传递给其处理程序函数的
参数将指向不应销毁或重新创建的预分配结构。代码应该将值附加到\u return
已经指向的\u return
,而不是创建自己的gbyterarray
gbyterarray
- 尽管您无论如何都不应该试图修改
的值,但您的代码这样做的方式是不正确的,最终会破坏\u return
指向的数据结构。这很可能解释了您看到的错误消息\u return
- 您的代码声明了
一个32位整数,但只将i
的第一个字节附加到字节数组中。这不会对每个机器体系结构产生您想要的效果i
gboolean
tutorial_calculator_handler_getdata (CalculatorIf *iface,
GByteArray ** _return,
GError **error)
{
THRIFT_UNUSED_VAR (iface);
THRIFT_UNUSED_VAR (error);
GByteArray *thing = g_byte_array_new();
*_return = g_byte_array_new();
guint8 i;
for (i = 0; i < 10; i++){
g_byte_array_append (thing, (guint8*) &i, sizeof(guint8));
}
g_byte_array_append(*_return, (guint8*) thing->data, thing->len);
return TRUE;
}
gboolean
教程\u计算器\u处理器\u获取数据(计算器f*iface,
GB字节数组**\u返回,
GError**错误)
{
节俭(iface);
节俭未使用价值(错误);
GByteArray*thing=g_byte_array_new();
*_return=g_byte_array_new();
Guint8i;
对于(i=0;i<10;i++){
g_字节_数组_追加(thing,(guint8*)&i,sizeof(guint8));
}
g_字节_数组_追加(*_返回,(guint8*)thing->data,thing->len);
返回TRUE;
}
以及客户端:
GByteArray *data = g_byte_array_new();
if (!error && calculator_if_getdata (client, &data, &error)) {
puts ("getdata()");
printf ("Data : %d\n", data);
guint8 i;
guint8 size = sizeof(guint8);
for(i=0;i<10;i++)
printf ("Data : %d\n", data->data[size*i]);
}
GByteArray*data=g_字节_数组_新();
if(!error&calculator\u if\u getdata(客户端、数据和错误)){
puts(“getdata()”);
printf(“数据:%d\n”,数据);
Guint8i;
guint8尺寸=尺寸(guint8);
对于(i=0;idata[size*i]);
}
感谢Simon的回复,请查看内联问题::如果我只是打印F(“%u\n”,返回);它输出0,这意味着我猜函数没有为它预先分配任何结构。现在,如果我自己为返回分配一个GByteArray(_return=g_byte_array_new();),那么它似乎正在工作(至少没有崩溃)。我现在唯一的问题是客户没有收到正确的数据。您也可以在这里找到修改后的版本,thrift存储库不包含二进制数据的测试用例或示例。我想一旦我的回购协议生效,我就可以把它加入回购协议。很好!你是对的binary
是一种基本类型,不是复杂类型(即不是集合),因此我上面写的是不正确的。
GByteArray *data = g_byte_array_new();
if (!error && calculator_if_getdata (client, &data, &error)) {
puts ("getdata()");
printf ("Data : %d\n", data);
guint8 i;
guint8 size = sizeof(guint8);
for(i=0;i<10;i++)
printf ("Data : %d\n", data->data[size*i]);
}