程式語言 - GNU - C/C++ - Protocol Buffers(nanopb)



參考資訊:
https://www.jianshu.com/p/cad578f48e0a
https://github.com/nanopb/nanopb/tree/master
https://github.com/afiskon/cpp-protobuf-example/tree/master
https://stackoverflow.com/questions/47704968/protoc-command-not-found-linux
https://stackoverflow.com/questions/62707863/how-to-encode-messages-with-map-using-google-protobuf-in-javascript-protocol

main.proto

syntax = "proto3";

message Test {
    string name = 1;
    int32 value = 2;
}

main.c

#include <stdio.h>
#include <pb_encode.h>
#include <pb_decode.h>

#include "main.pb.h"

bool write_pb(pb_ostream_t *stream, const pb_field_t *field, void * const *arg)
{
    char *str = *arg;

    pb_encode_tag_for_field(stream, field);
    return pb_encode_string(stream, (uint8_t *)str, strlen(str));
}

bool read_pb(pb_istream_t *stream, const pb_field_t *field, void **arg)
{
    int i = 0;
    char* tmp = *arg;
    uint64_t value = 0;

    while (stream->bytes_left) {
        pb_decode_varint(stream, &value);
        *(tmp + i) = value;
        i+= 1;
    }
    return true;
}

int main(int argc, char **argv)
{
    char tmp[128] = {0};
    char buffer[128] = {0};
    
    Test t1 = Test_init_zero;
    pb_ostream_t s1 = pb_ostream_from_buffer(buffer, sizeof(buffer));
    t1.name.funcs.encode = write_pb;
    t1.name.arg = "t1";
    t1.value = 100;
    pb_encode(&s1, Test_fields, &t1);

    Test t2 = Test_init_zero;
    t2.name.arg = &tmp;
    t2.name.funcs.decode = read_pb;
    pb_istream_t stream = pb_istream_from_buffer(buffer, s1.bytes_written);
    pb_decode(&stream, Test_fields, &t2);

    printf("t2.name %s\n", tmp);
    printf("t2.value %d\n", t2.value);
    return 0;
}

編譯、執行

$ protoc --nanopb_out=. main.proto
$ gcc main.c -o test main.pb.c -I. -lprotobuf-nanopb
$ ./test
    t2.name t1
    t2.value 100