Структура не возвращена клиенту с помощью клиента thrift c_glib

Я пытаюсь реализовать клиент-серверную программу в 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 (клиент, trans_packet и ошибка)
    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, "заголовок", 111, "данные", 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 ответа

Решение

Я мог бы найти решение для вышеуказанной проблемы.

Я изменил файл комиссионных следующим образом:

#!/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;
}

Теперь все, что я установил на сервере, получает это на клиенте.

Если есть другое решение, обновите ответ.

Структура, которую вы показали, не использует синтаксис 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;

В основном вы можете инициализировать указатель, используя экземпляр, например так:

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 *

Тогда в основном, вы можете пройти затем так:

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;
}
Другие вопросы по тегам