2016-10-19 4 views
0

Проводка моей работы для потомков. Реализовавшись после того, как я закончил свой последний пример на C++, мне на самом деле нужно было делать это в C все время (удивительный, верно?). Обе итерации заняли у меня значительные усилия в качестве программиста на Java, и я думаю, что много примеров кода там оставляет слишком много дыр - особенно, когда дело доходит до здания, что значительно сложнее из командной строки для тех, кто привык к используя, например, Eclipse, для создания проекта и обработки зависимостей.Простые Flatbuffers над ZeroMQ C примеру - Скопируйте структуру в flatbuffer через zmq и обратно в структуру снова

Как установить зависимости для OSX с варева:

brew install flatcc
brew install zeromq

Вам нужно все стандартные строитель двоичные файлы, установленные как хорошо. Я использовал GCC для компиляции с:

gcc publisher.c -o bin/zmq_pub -lzmq -lflatcc
gcc subscriber.c -o bin/zmq_sub -lzmq

Это предполагает, что вы установили zmq и flatcc библиотеки, которые должны получить слинкован в файл/USR/местные/включить после заваривания завершения установки. Как это:

zmq_cpub $ls -la /usr/local/include lrwxr-xr-x 1 user group 37 Oct 18 18:43 flatcc -> ../Cellar/flatcc/0.3.4/include/flatcc

Вы получите ошибку компиляции, такие как: Undefined symbols for architecture x86_64:, если у вас нет библиотеки правильно установлены/связаны между собой. Компилятор/компоновщик переименует функции и префикс их с помощью _ и потенциально путает вас. Как Undefined symbols for architecture x86_64 _flatcc_builder_init, хотя никогда не должно быть _flatcc_builder_init.

Это связано с тем, что связывание библиотек в C/C++ принципиально отличается от того, как в Java. Вместо определенного пути создания проекта, в который вы добавляете JAR, также есть известные места, где могут быть установлены внешние библиотеки C/C++. /usr/local/include, /usr/local/lib, /usr/lib, и /usr/include.

И не забудьте сгенерировать файлы заголовков для использования в локальном проекте после установки flatcc бинарного в путь:

flatcc -a Car.fbs

Это должно быть в значительной степени все препятствия, я столкнулся в моей поездке вниз по полосе С. Надеюсь, это поможет кому-то.

ответ

0

Car.fbs

namespace Test; 

table Car { 
    name: string; 
    model: string; 
    year: int; 
} 
root_type Car; 

Subscriber.c (прослушивает входящие структур)

// Hello World client 
#include "flatbuffers/Car_builder.h" // Generated by `flatcc`. 
#include "flatbuffers/flatbuffers_common_builder.h" 
#include <zmq.h> 

#undef ns 
#define ns(x) FLATBUFFERS_WRAP_NAMESPACE(Test, x) // Specified in the schema 

struct Car { 
    char* name; 
    char* model; 
    int year; 
}; 

int main (void) 
{ 
    printf ("Connecting to car world server...\n"); 
    void *context = zmq_ctx_new(); 
    void *requester = zmq_socket (context, ZMQ_REQ); 
    zmq_connect (requester, "tcp://localhost:5555"); 

    int request_nbr; 
    for (request_nbr = 0; request_nbr != 10; request_nbr++) { 
     char buffer [1024]; 
     printf ("Sending ready signal %d...\n", request_nbr); 
     zmq_send (requester, "Hello", 5, 0); 
     zmq_recv (requester, buffer, 1024, 0); 
     printf ("Received car %d\n", request_nbr); 
     ns(Car_table_t) car = ns(Car_as_root(buffer)); 
     int year = ns(Car_year(car)); 
     flatbuffers_string_t model = ns(Car_model(car)); 
     flatbuffers_string_t name = ns(Car_name(car)); 

     struct Car nextCar; 
     // no need to double up on memory!! 
     // strcpy(nextCar.model, model); 
     // strcpy(nextCar.name, name); 
     nextCar.model = model; 
     nextCar.name = name; 
     nextCar.year = year; 

     printf("Year: %d\n", nextCar.year); 
     printf("Name: %s\n", nextCar.name); 
     printf("Model: %s\n", nextCar.model); 
    } 
    zmq_close (requester); 
    zmq_ctx_destroy (context); 
    return 0; 
} 

Publisher.c (посылает через zmq структур гнездо):

// Hello World server 

#include "flatbuffers/Car_builder.h" // Generated by `flatcc`. 
#include "flatbuffers/flatbuffers_common_builder.h" 
#include <zmq.h> 
#include <unistd.h> 
#include <time.h> 

#undef ns 
#define ns(x) FLATBUFFERS_WRAP_NAMESPACE(Test, x) // specified in the schema 

struct Car { 
    char name[10]; 
    char model[10]; 
    int year; 
}; 

struct Car getRandomCar() { 
    struct Car randomCar; 
    int a = rand(); 
    if ((a % 2) == 0) { 
     strcpy(randomCar.name, "Ford"); 
     strcpy(randomCar.model, "Focus"); 
    } else { 
     strcpy(randomCar.name, "Dodge"); 
     strcpy(randomCar.model, "Charger"); 
    } 
    randomCar.year = rand(); 
    return randomCar; 
} 

int main (void) 
{ 
    srand(time(NULL)); 

    // Socket to talk to clients 
    void *context = zmq_ctx_new(); 
    void *responder = zmq_socket (context, ZMQ_REP); 
    int rc = zmq_bind (responder, "tcp://*:5555"); 
    assert (rc == 0); 
    int counter = 0; 

    while (1) { 
     struct Car c = getRandomCar(); 

     flatcc_builder_t builder, *B; 
     B = &builder; 
     // Initialize the builder object. 
     flatcc_builder_init(B); 
     uint8_t *buf; // raw buffer used by flatbuffer 
     size_t size; // the size of the flatbuffer 
     // Convert the char arrays to strings 
     flatbuffers_string_ref_t name = flatbuffers_string_create_str(B, c.name); 
     flatbuffers_string_ref_t model = flatbuffers_string_create_str(B, c.model); 

     ns(Car_start_as_root(B)); 
     ns(Car_name_add(B, name)); 
     ns(Car_model_add(B, model)); 
     ns(Car_year_add(B, c.year)); 
     ns(Car_end_as_root(B)); 
     buf = flatcc_builder_finalize_buffer(B, &size); 

     char receiveBuffer [10]; 
     zmq_recv (responder, receiveBuffer, 10, 0); 
     printf ("Received ready signal. Sending car %d.\n", counter); 
     sleep (1);   // Do some 'work' 
     zmq_send (responder, buf, size, 0); 
     counter++; 

     free(buf); 
    } 
    return 0; 
}