Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/google-sheets/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
为什么我的节俭型(c_glib)客户会以“失败”而失败;无效指针";错误_C_Thrift_Glib - Fatal编程技术网

为什么我的节俭型(c_glib)客户会以“失败”而失败;无效指针";错误

为什么我的节俭型(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,

我正在用C(g_lib)创建一个简单的thrift服务器/客户端程序。 这是我的节俭IDL文件的外观:

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
    指向的数据结构。这很可能解释了您看到的错误消息

  • 您的代码声明了
    i
    一个32位整数,但只将
    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]);

  }