title: C++ Serialization Guide sidebar_position: 0 id: cpp_serialization_index license: | Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Apache Fory™ is a blazing fast multi-language serialization framework powered by JIT compilation and zero-copy techniques, providing up to ultra-fast performance while maintaining ease of use and safety.
The C++ implementation provides high-performance serialization with compile-time type safety using modern C++17 features and template metaprogramming.
The C++ implementation supports both CMake and Bazel build systems.
The easiest way to use Fory is with CMake's FetchContent module:
cmake_minimum_required(VERSION 3.16) project(my_project LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) if(MSVC) add_compile_options(/Zc:preprocessor) endif() include(FetchContent) FetchContent_Declare( fory GIT_REPOSITORY https://github.com/apache/fory.git GIT_TAG v0.14.1 SOURCE_SUBDIR cpp ) FetchContent_MakeAvailable(fory) add_executable(my_app main.cc) target_link_libraries(my_app PRIVATE fory::serialization)
Then build and run:
mkdir build && cd build cmake .. -DCMAKE_BUILD_TYPE=Release cmake --build . --parallel ./my_app
Create a MODULE.bazel file in your project root:
module( name = "my_project", version = "1.0.0", ) bazel_dep(name = "rules_cc", version = "0.1.1") bazel_dep(name = "fory", version = "0.14.1") git_override( module_name = "fory", remote = "https://github.com/apache/fory.git", commit = "v0.14.1", # Or use a specific commit hash for reproducibility )
Create a BUILD file for your application:
cc_binary( name = "my_app", srcs = ["main.cc"], deps = ["@fory//cpp/fory/serialization:fory_serialization"], )
Then build and run:
bazel build //:my_app bazel run //:my_app
For local development, you can use local_path_override instead:
bazel_dep(name = "fory", version = "0.14.1") local_path_override( module_name = "fory", path = "/path/to/fory", )
See the examples/cpp directory for complete working examples:
#include "fory/serialization/fory.h" using namespace fory::serialization; // Define a struct struct Person { std::string name; int32_t age; std::vector<std::string> hobbies; bool operator==(const Person &other) const { return name == other.name && age == other.age && hobbies == other.hobbies; } }; // Register the struct with Fory (must be in the same namespace) FORY_STRUCT(Person, name, age, hobbies); int main() { // Create a Fory instance auto fory = Fory::builder() .xlang(true) // Enable cross-language mode .track_ref(false) // Disable reference tracking for simple types .build(); // Register the type with a unique ID fory.register_struct<Person>(1); // Create an object Person person{"Alice", 30, {"reading", "coding"}}; // Serialize auto result = fory.serialize(person); if (!result.ok()) { // Handle error return 1; } std::vector<uint8_t> bytes = std::move(result).value(); // Deserialize auto deser_result = fory.deserialize<Person>(bytes); if (!deser_result.ok()) { // Handle error return 1; } Person decoded = std::move(deser_result).value(); assert(person == decoded); return 0; }
Apache Fory™ C++ provides two variants for different threading needs:
// Single-threaded Fory - fastest, NOT thread-safe auto fory = Fory::builder() .xlang(true) .build();
// Thread-safe Fory - uses context pools auto fory = Fory::builder() .xlang(true) .build_thread_safe(); // Can be used from multiple threads safely std::thread t1([&]() { auto result = fory.serialize(obj1); }); std::thread t2([&]() { auto result = fory.serialize(obj2); });
Tip: Perform type registrations before spawning threads so every worker sees the same metadata.