首页 > 解决方案 > 表向量,平面缓冲区 C

问题描述

我正在用 C 语言试验 flatbuffers,只是感觉一下。我有一个奇怪的问题。好吧,很可能有几个。

我正在构建平面缓冲区并以正确的方式添加所有正确的组件。但是,当我尝试读取表向量时,_vec_len(T) 返回大小为 0,即使当我对缓冲区进行 hexdump 时,我可以清楚地看到所述表被添加到缓冲区中/从缓冲区中删除。

我已经使用了更多的方法来使表格的向量变得可读,我无法计算。大多数都以类型不匹配的编译错误结束。实际编译的没有一个导致 _vec_len(T) 返回 0 以外的任何值。

我也尝试过使用 _vec_at(0),但这会导致断言失败,指出给定索引超出范围。

在这一点上,我要么:a) 遗漏了一些非常简单的东西,b) 构建 flatbuffer 完全错误,或者 c) 对 flatbuffer 的构建方式做出了完全不正确的假设。

我附上了我的架构和源代码,以及程序的调试输出。

(我在发布代码块后意识到代码块不包含行号。)似乎失败的行size_t hops_vec_len = TransitHop_vec_len(hopsTable);位于靠近底部的 C 代码中。// test_root routing要么这样,要么从顶部附近开始的整个街区都是错误的。

据我了解,使用 _start(B) 和 _end(B),添加到架构的所述组件的所有内容都应该添加到缓冲区并放入 v-tables 以自动访问。

所以,我不知道该去哪里。谁能指出我做错了什么/误解?任何帮助是极大的赞赏。


flatbuffers_test.fbs


table Ping {
    sent:uint;
}

table Pong {
    sent:uint;
}

union Type {
    Ping,
    Pong,
}

enum ServerTypes:ubyte {
    mach = 0,
    cnc,
    mill,
    press,
    drill,
    controller,
    unknown,
}

table TransitHop {
    serverID: uint64;
    serverType: ServerTypes;
}

table TransitHeader {
    from: TransitHop;
    to: TransitHop;
    hops: [TransitHop];
}

table TransitSequence {
    transitID:  uint64;
    begin:      uint8;
    current:    uint8;
    total:      uint8;
}

table TestRoot {
    type: Type;
    sequence: TransitSequence;
    routing: TransitHeader;
}

root_type TestRoot;

flatbuffers_test.c

#include <stdio.h>
#include "flatcc/support/hexdump.h"
#include "flatbuffers_test_builder.h"

// This allows us to verify result in optimized builds.
#define test_assert(x) do { if (!(x)) { assert(0); return -1; }} while(0)

int main(void) {

    flatcc_builder_t builder, *B;
    B = &builder;
    void *buff = NULL;
    size_t size;
    FILE *fh = NULL;

    flatcc_builder_init(B);

    printf("TestRoot - Routing\n\n");

    TestRoot_start_as_root(B);
    {
        // test_root type
        {
            Ping_ref_t testType = Ping_create(B, 0); // the 0 here would be the time the ping is sent

            TestRoot_type_add(B, Type_as_Ping(testType));
        }

        // test_root sequence
        {
            TransitSequence_ref_t sequence = TransitSequence_create(B, 1, 1, 1, 1);

            TestRoot_sequence_add(B, sequence);
        }

        // test_root routing
        {
            TransitHeader_start(B);
            {
                TransitHop_ref_t hopFrom = 0;
                TransitHop_ref_t hopTo = 0;
                TransitHeader_hops_start(B);
                {
                    hopFrom = TransitHop_create(B, 1, ServerTypes_mach);
                    TransitHop_create(B, 2, ServerTypes_controller);
                    TransitHop_create(B, 3, ServerTypes_controller);
                    hopTo = TransitHop_create(B, 4, ServerTypes_cnc);
                }
                TransitHop_ref_t hops = TransitHeader_hops_end(B);

                TransitHeader_from_add(B, hopFrom);
                TransitHeader_to_add(B, hopTo);
                TransitHeader_hops_add(B, hops);
            }
            TransitHeader_ref_t routing = TransitHeader_end(B);

            TestRoot_routing_add(B, routing);
        }
    }
    TestRoot_end_as_root(B);

    buff = flatcc_builder_finalize_aligned_buffer(&builder, &size);

    printf("flatbuffer size: %ld\n", size);

    TestRoot_table_t test_root = TestRoot_as_root(buff);

    test_assert(test_root != 0);

    int type_present = TestRoot_type_is_present(test_root);
    int sequence_present = TestRoot_sequence_is_present(test_root);
    int routing_present = TestRoot_routing_is_present(test_root);

    printf("    type present: %d\n", type_present);
    if (type_present == 1) {
        Type_union_type_t type = TestRoot_type_type(test_root);
        printf("\ttype: %s\n", Type_type_name(type));
    }

    printf("sequence present: %d\n", sequence_present);
    if (sequence_present == 1) {
        TransitSequence_table_t sequence = TestRoot_sequence(test_root);
        printf("\ttransitID: %ld\n", TransitSequence_transitID(sequence));
        printf("\t    begin: %d\n", TransitSequence_begin(sequence));
        printf("\t  current: %d\n", TransitSequence_current(sequence));
        printf("\t    total: %d\n", TransitSequence_total(sequence));
    }

    printf(" routing present: %d\n", routing_present);

    if (routing_present == 1) {
        TransitHeader_table_t routing = TestRoot_routing(test_root);

        TransitHop_table_t from = TransitHeader_from(routing);
        TransitHop_table_t to = TransitHeader_to(routing);
        TransitHop_vec_t hopsTable = TransitHeader_hops(routing);

        test_assert(hopsTable != 0);

        ServerTypes_enum_t serverTypeFrom = TransitHop_serverType(from);
        ServerTypes_enum_t serverTypeTo = TransitHop_serverType(to);

        printf("\tfrom: %ld\t%s\n", TransitHop_serverID(from), ServerTypes_name(serverTypeFrom));
        printf("\t  to: %ld\t%s\n", TransitHop_serverID(to), ServerTypes_name(serverTypeTo));

        int hops_present = TransitHeader_hops_is_present(routing);

        if (hops_present == 1) {
//            // this causes [Assertion `flatbuffers_vec_len(vec) > (i) && "index out of range"' failed.] ?????
//            TransitHop_table_t hopsTableZero = TransitHop_vec_at(hopsTable, 0);
//
//            test_assert(hopsTableZero == 0);


            size_t hops_vec_len = TransitHop_vec_len(hopsTable);
            printf("\thops: %lu\n", hops_vec_len);

            for (size_t i = 0; i < hops_vec_len; i++) {
                printf("\t\t%lu\n", i);
            }
        }
    }

    fh = fopen("/tmp/fbhd-test1", "w");

    if (fh == NULL) {
        printf("Cannot open /tmp/fbhd-test1 for writing\n\n");
        return -1;
    } else {
        hexdump(NULL, buff, size, fh);
    }

    fclose(fh);

    flatcc_builder_aligned_free(buff);

    return 0;
}

调试1.txt

Program output with the vector of tables being added to the flatbuffer:

TestRoot - Routing

flatbuffer size: 188
    type present: 1
        type: Ping
sequence present: 1
        transitID: 1
            begin: 1
          current: 1
            total: 1
 routing present: 1
        from: 1 mach
          to: 4 cnc
        hops: 0



00000000  0c 00 00 00 54 45 53 54  00 00 00 00 5c ff ff ff  |....TEST....\...|
00000010  01 00 00 00 70 00 00 00  5c 00 00 00 04 00 00 00  |....p...\.......|
00000020  7a ff ff ff 0c 00 00 00  3c 00 00 00 08 00 00 00  |z.......<.......|
00000030  00 00 00 00 96 ff ff ff  04 00 00 00 00 00 00 00  |................|
00000040  01 00 00 00 a6 ff ff ff  03 00 00 00 00 00 00 00  |................|
00000050  05 00 00 00 b6 ff ff ff  02 00 00 00 00 00 00 00  |................|
00000060  05 00 00 00 cc ff ff ff  01 00 00 00 00 00 00 00  |................|
00000070  00 00 00 00 e8 ff ff ff  01 00 00 00 00 00 00 00  |................|
00000080  01 01 01 00 fc ff ff ff  04 00 04 00 0c 00 0f 00  |................|
00000090  04 00 0c 00 0d 00 0e 00  06 00 0c 00 04 00 08 00  |................|
000000a0  0d 00 04 00 0c 00 0a 00  10 00 08 00 0c 00 04 00  |................|
000000b0  0c 00 14 00 04 00 08 00  0c 00 10 00              |............|





Program output without the vector of tables being added to the flatbuffer:

TestRoot - Routing

flatbuffer size: 74
    type present: 1
        type: Ping
sequence present: 1
        transitID: 1
            begin: 1
          current: 1
            total: 1
 routing present: 0



00000000  0c 00 00 00 54 45 53 54  00 00 00 00 cc ff ff ff  |....TEST........|
00000010  01 00 00 00 18 00 00 00  04 00 00 00 e8 ff ff ff  |................|
00000020  01 00 00 00 00 00 00 00  01 01 01 00 fc ff ff ff  |................|
00000030  04 00 04 00 0c 00 0f 00  04 00 0c 00 0d 00 0e 00  |................|
00000040  0a 00 10 00 04 00 08 00  0c 00                    |..........|





Program output when trying to use _vec_at(0):

TestRoot - Routing

flatbuffer size: 188
    type present: 1
        type: Ping
sequence present: 1
        transitID: 1
            begin: 1
          current: 1
            total: 1
 routing present: 1
        from: 1 mach
          to: 4 cnc
flatbuffers_test: /home/vadtec/schema/generated/flatbuffers_test_reader.h:192: TransitHop_vec_at: Assertion `flatbuffers_vec_len(vec) > (i) && "index out of range"' failed.

标签: cvectorflatbuffers

解决方案


我收到了来自 flatcc 作者的回复。

有关完整响应,请参阅https://groups.google.com/g/flatbuffers/c/mjkyhbA6vS8


推荐阅读