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