Open-source project
Neargye/hello_tf_c_api avatar
Neargye/hello_tf_c_api

hello_tf_c_api: TensorFlow C API Examples That Are Not a Library

Neural Network TensorFlow C API

472 stars135 forksC++MIT

At a glance

What is it?
Neargye/hello_tf_c_api is a CMake-driven set of small TensorFlow C API examples for Windows, Linux and macOS, plus a thin helper target. It is teaching material and a wiring reference, not a dependency you add to a build.
Who is it for?
Adopt it as a reference when you need to link the TensorFlow C API by hand or want to see how a TF_Session, a GraphDef and a tensor buffer fit together in C++17. Do not adopt it as a package: the README states the repository is maintained as local examples plus tests, and that another project needing a small part of it should copy the relevant source and wire it to its own TensorFlow target.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 69 days ago.
What is it written in?
Mainly C++, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The gap between the TensorFlow Python tutorials and a C++ binary

Most TensorFlow material assumes Python. If you are shipping a C++ application and want to run inference in-process, you end up against the C API: TF_Graph, TF_Session, TF_Tensor, and a set of headers that ship inside the Python wheel. The documentation for that layer is sparse, and the failure modes are not obvious. hello_tf_c_api exists to close that gap with small, runnable examples rather than prose. The README lists fourteen of them under src/, from hello_tf.cpp through load_graph.cpp, create_tensor.cpp, session_run.cpp, repeated_inference.cpp, tensor_info.cpp and graph_info.cpp. Each one isolates a single operation, which is the point. You read session_run.cpp to see the session lifecycle, and interface.cpp or batch_interface.cpp to see a helper wrapper around it. The audience is narrow: a C++ developer who already knows what a GraphDef is and needs the C-level call sequence, not someone learning machine learning. The repository also carries models/graph.pb in-tree, so no model download is needed before the first build.

What the build actually does: wheel extraction, imported target, DLL copy

The mechanism is more interesting than the examples. CMake downloads TensorFlow 2.21.0 from the Python wheel into a build-local cache at <build>/_deps/tensorflow/python. That is the default. It requires Python with pip during the configure step, which is an unusual constraint for a C++ project and worth understanding before you run it in a locked-down build environment. The CMake file then creates an imported tensorflow target, a hello_tf_utils helper library target, and copies required runtime libraries where needed. On Windows, it copies the TensorFlow runtime DLLs into the build output directories, which is the step people usually get wrong by hand. Examples that use the helper API link hello_tf_utils; examples that demonstrate raw C API usage call target_link_tensorflow instead. That split is deliberate and it tells you what the repository is: two parallel tracks, one showing the bare API and one showing a convenience layer, so you can compare them. There is no installed package, no exported config file, and no versioned release artefact. The README says the repository is maintained as local examples plus tests, not as a packaged dependency.

Getting it running on each platform, and the configure flags that matter

The README gives three platform blocks. On Windows: clone with --depth 1, mkdir build, cd build, then cmake -A x64 .., cmake --build . --config Release, and ctest --output-on-failure -C Release. On Linux: cmake .. -DCMAKE_BUILD_TYPE=Release, cmake --build . -j 4, ctest --output-on-failure. On macOS the commands match Windows except the generator flag is dropped and the build type is passed at configure time. The flags that change behaviour are the ones to read closely. -DTENSORFLOW_ROOT=/path/to/tensorflow points at an existing wheel extraction; auto-fetch only writes to the default build-local cache and refuses to overwrite an external TENSORFLOW_ROOT. -DHELLO_TF_FETCH_TENSORFLOW=OFF requires a pre-existing extraction and disables downloads during configure, which is the flag you want on an air-gapped or reproducible build machine. -DHELLO_TF_BUILD_EXAMPLES=OFF configures only the helper library without example executables. -DBUILD_TESTING=OFF drops tests, following CMake's standard option. OpenCV is optional: if CMake finds it, the OpenCV image-file example is built and tested. Tests use doctest from test/3rdparty, and CI also runs an ASan/UBSan job on Ubuntu, which is a reasonable signal that the examples are exercised under sanitizers rather than merely compiled.

The checkpoint trap: LoadGraph does not restore variables

The most useful paragraph in the README is a warning, not a feature. tf_utils::LoadGraph only imports a GraphDef. If a graph needs checkpoint restore operations, you must create the session first and then call tf_utils::RestoreCheckpoint(session, graph, ...) on that session. The reason is stated plainly: TensorFlow variable state belongs to TF_Session, not to TF_Graph. This is exactly the kind of ordering mistake that produces a model that loads without error and then predicts garbage, and the documentation calls it out rather than hiding it. It also shapes how you should read the examples: load_graph.cpp shows import, while session_run.cpp shows the session, and the restore step sits between them conceptually even though the committed models/graph.pb does not require it. If you are porting a training checkpoint to C++ inference, this ordering is the first thing to verify in your own code. The repository gives you the helper signature but not a worked restore example in the listed source files, so expect to write that path yourself against the C API.

Where it stops being the right tool

Three boundaries are visible from the material. First, it is not a dependency. There is no package to consume, no release artefacts, and the README explicitly directs you to copy the relevant example or helper source and wire it to your own TensorFlow target if you need a small part of it. Treating it as a library you track and upgrade will not work, because there is nothing to track. Second, the default build reaches the network during configure and needs pip. On a machine without Python, or behind a proxy that blocks the wheel download, the default path fails; you must pre-extract a wheel and pass -DTENSORFLOW_ROOT with -DHELLO_TF_FETCH_TENSORFLOW=OFF. Third, the scope is inference plumbing, not model tooling. The README points elsewhere for model preparation and optimisation, and the committed graph is described as a small GraphDef for the examples. There is no conversion pipeline, no quantisation step, and no serving layer here. If your problem is getting a SavedModel into a deployable form, this repository is the wrong end of the problem.

Against TensorFlow Lite and the C++ wrapper route

The obvious alternative is TensorFlow Lite, which the README links to under further reading for model optimisation. The difference in approach is architectural. TensorFlow Lite targets a compact interpreter and a converted .tflite flatbuffer, aimed at mobile and embedded deployment with a smaller runtime. hello_tf_c_api links the full TensorFlow native libraries extracted from the Python wheel, which is a much heavier dependency and gives you the complete op set and the full TF_Session and TF_Graph model. If your deployment target is a phone or a device with tight memory, Lite is the direction the project's own links point you toward. If you are on a desktop or server with the full runtime available and you want the same graph execution semantics as the Python side, the C API path shown here is the closer match. A second alternative is the C++ API, which wraps the same underlying machinery in classes and RAII. The examples here deliberately stay at the C level, which means more manual lifetime management but fewer moving parts between your code and the runtime.

Maintenance cost and what the MIT licence covers

The repository is licensed under MIT, which permits use, modification and redistribution provided the copyright notice and permission notice are retained. That is permissive and imposes no copyleft obligation on your own code. Note the practical consequence of copying source rather than linking a package: once you lift an example or the helper into your project, you own that code. Upstream fixes will not reach you automatically, and the MIT notice still needs to travel with the copied files. The pinned TensorFlow version in the default fetch is 2.21.0, so a future TensorFlow upgrade means editing the fetch logic or supplying your own TENSORFLOW_ROOT extraction. The project is not archived, and the last push recorded is recent, but the README describes it as examples plus tests, so plan for the code you copy to be yours to maintain. This is not legal advice; check the LICENSE file in the repository and your own organisation's policy before redistributing copied source.

Editorial conclusion

Adopt it as a reference when you need to link the TensorFlow C API by hand or want to see how a TF_Session, a GraphDef and a tensor buffer fit together in C++17. Do not adopt it as a package: the README states the repository is maintained as local examples plus tests, and that another project needing a small part of it should copy the relevant source and wire it to its own TensorFlow target. Before committing, verify that CMake can fetch or find TensorFlow 2.21.0 on your machine, then run ctest --output-on-failure to confirm the examples execute, and check whether your inference path needs RestoreCheckpoint, which LoadGraph alone will not perform.

Official sources

  1. Issues
  2. License: MIT
  3. Neargye/hello_tf_c_api on GitHub
  4. README
Community notes

Community notes