为后代发布我的作品。在完成我在C ++中的最后一个例子之后实现了我实际上需要在C中一直这样做(真棒,对吧?)。这两次迭代都让我作为一名Java程序员付出了相当大的努力,我认为很多示例代码都留下了太多的漏洞 - 尤其是,当涉及到构建时,从命令行来说相当困难曾经习惯使用Eclipse的人来构建项目并处理依赖项。
如何使用brew安装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库,这些库应该在brew完成安装后符号链接到/ usr / local / include。像这样:
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中的库根本不同。您也可以安装外部C / C ++库的已知位置,而不是添加JAR的特定项目构建路径。 /usr/local/include
,/usr/local/lib
,/usr/lib
和/usr/include
。
在将flatcc二进制文件安装到您的路径后,不要忘记生成要在本地项目中使用的头文件:
flatcc -a Car.fbs
这应该是我在C车道上行驶时遇到的每一个障碍。希望它可以帮助那里的人。
答案 0 :(得分: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;
}