结构未使用thrift c_glib客户端返回给客户端

时间:2015-04-13 13:29:52

标签: c thrift thrift-protocol

我正在尝试使用thrift在c(c_glib)中实现客户端/服务器程序。

我已将客户端/服务器传递变量实现为函数参数。现在我需要将结构作为函数参数传递。

我正在使用的thrift文件在下面给出

#!/usr/local/bin/thrift --gen c_glib


struct packet {
        1: i32 header,
        2: i32 data
}

service Calculator {
        void ping(),
        i32 calculate(1:i32 id, 2:i32 num),
        void stop_transfer(),
        void set_packet(1:packet pac_data)

}

我通过结构的步骤是:

  • 在客户端
    1。 g_object_new(TYPE_PACKET,NULL)
    2。将结构指针传递给服务器。 calculator_if_set_packet(client,trans_packet,& error)
    3。 g_object_get(tans_packet," header",& head," data",& dat,NULL)来获取服务器中的数据集4。打印结构以显示服务器中的数据集反映在客户端

客户端相关代码如下:

int main (void) 
{
    gint head;
    gint dat;

    packet *trans_packet;

    trans_packet = g_object_new (TYPE_PACKET, NULL);

    if(!error && calculator_if_set_packet (client, trans_packet, &error)) {
        g_object_get((packet *) trans_packet,
             "header", &head,
             "data", &dat,
             NULL);

        printf("struct->header : %d\n", head);
        printf("struct->data : %d\n", dat);
    }

    g_object_unref (trans_packet);

}
  • 在服务器端
    1。 g_object_get(pac_data," header",& header," data",& data,NULL)获取pac_data的属性.2。 g_object_setg_object_get(tans_packet," header",111," data",999,NULL)

服务器端功能如下所示

static gboolean 
tutorial_calculator_handler_set_packet(CalculatorIf *iface,
                                  const packet * pac_data,
                                  GError **error)
{
    gint header;
    gint data;

    THRIFT_UNSED_VAR (iface);
    THRIFT_UNUSED_VAR (error);

    g_object_get((packet *) pac_data,
             "header", &header,
             "data", &data,
             NULL);

    g_object_set((packet *) pac_data,
             "header", 123,
             "data", 999,
             NULL);

    return TRUE;
}

当我这样做时,服务器在调用calculator_if_set_packet()时没有向客户端返回任何内容。

任何人都可以帮我这个吗?

2 个答案:

答案 0 :(得分:0)

您显示的结构不使用C语法,即使对于位字段:

struct packet {  //Not C syntax
        1: i32 header, //1nvalid struct field declaration
        2: i32 data    //invalid struct field declaration
}                      //missing ;  

您没有显示将结构作为参数的函数原型,但是例如您的结构被定义为:

typedef struct {
    int header;
    int data;
} PACKET;  //symbol PACKET would be used like your "struct packet"

然后使用这个typedef,您可以创建一个实例,并指向该结构,如下所示:

PACKET包,* pPacket;

在main中,您可以使用实例初始化指针,如下所示:

int main(void)
{
    //pointer   instance
      pPacket = &packet;
      pPacket = malloc(sizeof(PACKET));//provide memory for pointer
      ...

      free(pPacket);//free dynamic memory 
      return 0;
}

然后,比如说你有一个函数原型接受一个实例,另一个接受指向该结构的指针:

void someFunc1(PACKET pkt);  // takes an instance of PACKET
void someFunc2(PACKET *pkt);  //takes an instance of PACKET *

然后在main中,你可以像这样传递:

int main(void)
{
    pPacket = &packet;  //initialize pointer using instance
    pPacket = malloc(sizeof(PACKET));//provide memory for pointer

    someFunc1(packet);  //pass instance of PACKET
    someFunc2(pPacket); //pass pointer to PACKET
    someFunc2(&packet); //same as previous
    ...
    free(pPacket);//free dynamic memory 
    return 0;
}

答案 1 :(得分:0)

我可以找到解决上述问题的方法。

我按如下方式更改了thrift文件:

#!/usr/local/bin/thrift --gen c_glib

struct packet {
    1: i32 header,
    2: i32 data
}

service Calculator {
    void ping(),
    i32 calculate(1:i32 id, 2:i32 num),
    void stop_transfer(),
    packet set_packet(1:packet pac_data)
}

客户端和服务器部分的相应修改如下:

在客户端部分

int main (void) 
{
    gint head;
    gint dat;

    packet *trans_packet;
    packet *ret_packet;

    trans_packet = g_object_new (TYPE_PACKET, NULL);
    ret_packet = g_object_new (TYPE_PACKET, NULL);

    if(!error && calculator_if_set_packet (client, &ret_packet, trans_packet, &error)) {
        g_object_get((packet *) ret_packet,
             "header", &head,
             "data", &dat,
             NULL);

        printf("struct->header : %d\n", head);
        printf("struct->data : %d\n", dat);
    }

    g_object_unref (trans_packet);
    g_object_unref (ret_packet);
}

在服务器部分

static gboolean 
tutorial_calculator_handler_set_packet(CalculatorIf *iface,
                              packet ** _return,
                              const packet * pac_data,
                              GError **error)
{
    gint header;
    gint data;

    THRIFT_UNSED_VAR (iface);
    THRIFT_UNUSED_VAR (error);

    g_object_get((packet *) pac_data,
             "header", &header,
             "data", &data,
             NULL);

    g_object_set(*_return,
             "header", 123,
             "data", 999,
             NULL);

    return TRUE;
}

现在无论我在服务器中设置了什么,都可以在客户端获得。

如果还有其他解决方案,请更新答案。