The C language binding exists in a separate project named FlatCC.
The flatcc
C schema compiler can generate code offline as well as
online via a C library. It can also generate buffer verifiers and fast
JSON parsers, printers.
Great care has been taken to ensure compatibily with the main flatc
project.
CI builds recent versions of gcc, clang and MSVC on OS-X, Ubuntu, and
Windows, and occasionally older compiler versions. See main project Status.
Other platforms may well work, including Centos, but are not tested
regularly.
The monster sample project was specifically written for C99 in order to
follow the C++ version and for that reason it will not work with MSVC
2010.
In the tutorial we used the call Monster_create_as_root
to create the
root buffer object since this is easier in simple use cases. Sometimes
we need more modularity so we can reuse a function to create nested
tables and root tables the same way. For this we need theflatcc_builder_buffer_create_call
. It is best to keep flatcc_builder
calls isolated at the top driver level, so we get:
The same principle applies with start/end
vs start/end_as_root
in
the top-down approach.
The tutorial uses a bottom up approach. In C it is also possible to use
a top-down approach by starting and ending objects nested within each
other. In the tutorial there is no deep nesting, so the difference is
limited, but it shows the idea:
The C-API does support reading binary schema (.bfbs)
files via code generated from the reflection.fbs
schema, and an
example usage
shows how to use this. The reflection schema files are pre-generated
in the runtime distribution.
The C-API does not support mutating reflection like C++ does, nor does
the reader interface support mutating scalars (and it is generally
unsafe to do so even after verification).
The generated reader interface supports sorting vectors in-place after
casting them to a mutating type because it is not practical to do so
while building a buffer. This is covered in the builder documentation.
The reflection example makes use of this feature to look up objects by
name.
It is possible to build new buffers using complex objects from existing
buffers as source. This can be very efficient due to direct copy
semantics without endian conversion or temporary stack allocation.
Scalars, structs and strings can be used as source, as well vectors of
these.
It is currently not possible to use an existing table or vector of table
as source, but it would be possible to add support for this at some
point.
The FLATBUFFERS_WRAP_NAMESPACE
approach used in the tutorial is convenient
when each function has a very long namespace prefix. But it isn't always
the best approach. If the namespace is absent, or simple and
informative, we might as well use the prefix directly. The
reflection example
mentioned above uses this approach.
Not all languages support testing if a field is present, but in C we can
elaborate the reader section of the tutorial with tests for this. Recall
that mana
was set to the default value 150
and therefore shouldn't
be present.
In the tutorial we used a single call to add a union. Here we show
different ways to accomplish the same thing. The last form is rarely
used, but is the low-level way to do it. It can be used to group small
values together in the table by adding type and data at different
points in time.
flatc
tool?It was considered how the C code generator could be integrated into theflatc
tool, but it
would either require that the standalone C implementation of the schema
compiler was dropped, or it would lead to excessive code duplication, or
a complicated intermediate representation would have to be invented.
Neither of these alternatives are very attractive, and it isn't a big
deal to use the flatcc
tool instead of flatc
given that the
FlatBuffers C runtime library needs to be made available regardless.