Configuration
This page covers C++ runtime configuration. Fory::builder() creates xlang
payloads by default, and omitted compatible mode resolves to compatible mode in
xlang. Native mode is selected explicitly with .xlang(false) and defaults to
schema-consistent payloads.
Builder Pattern
Use Fory::builder() to construct Fory instances with custom configuration:
#include "fory/serialization/fory.h"
using namespace fory::serialization;
// Xlang mode with compatible schema evolution.
auto fory = Fory::builder().xlang(true).build();
// Schema-consistent xlang payloads.
auto fory = Fory::builder()
.xlang(true)
.compatible(false)
.build();
// Native mode for C++-only traffic.
auto fory = Fory::builder()
.xlang(false)
.build();
// Native mode with compatible schema evolution.
auto fory = Fory::builder()
.xlang(false)
.track_ref(true)
.max_dyn_depth(10)
.compatible(true)
.build();
Configuration
xlang(bool)
Select the wire mode.
auto fory = Fory::builder()
.xlang(false)
.build();
When true, C++ writes the xlang wire format used by Java, Python, Go, Rust,
JavaScript, C#, Swift, and Dart. When false, C++ writes native-mode payloads
for C++-only traffic.
Default: true
compatible(bool)
Enable compatible schema evolution.
auto fory = Fory::builder()
.xlang(true)
.compatible(true)
.build();
When enabled, supports reading data serialized with different schema versions. When omitted, xlang mode defaults to compatible mode. Native mode defaults to schema-consistent mode and uses compatible mode only when this option is set.
Default: true in xlang mode; false in native mode
track_ref(bool)
Enable/disable reference tracking for shared and circular references.
auto fory = Fory::builder()
.xlang(true)
.track_ref(true) // Enable reference tracking
.build();
When enabled, avoids duplicating shared objects and handles cycles.
Default: true
max_dyn_depth(uint32_t)
Set maximum allowed nesting depth for dynamically-typed objects.
auto fory = Fory::builder()
.xlang(true)
.max_dyn_depth(10) // Allow up to 10 levels
.build();
This limits the maximum depth for nested polymorphic object serialization (e.g., shared_ptr<Base>, unique_ptr<Base>). This prevents stack overflow from deeply nested structures in dynamic serialization scenarios.
Default: 5
When to adjust:
- Increase: For legitimate deeply nested data structures
- Decrease: For stricter security requirements or shallow data structures
check_struct_version(bool)
Enable/disable struct version checking.
auto fory = Fory::builder()
.xlang(true)
.compatible(false)
.check_struct_version(true) // Enable version checking
.build();
When enabled, validates type hashes to detect schema mismatches.
Default: false
Thread-Safe vs Single-Threaded
Single-Threaded (Fastest)
auto fory = Fory::builder().xlang(true).build(); // Returns Fory
Single-threaded Fory is the fastest option, but NOT thread-safe. Use one instance per thread.
Thread-Safe
auto fory = Fory::builder().xlang(true).build_thread_safe(); // Returns ThreadSafeFory
ThreadSafeFory uses a pool of Fory instances to provide thread-safe serialization. Slightly slower due to pool overhead, but safe to use from multiple threads concurrently.
Configuration Summary
| Option | Description | Default |
|---|---|---|
xlang(bool) | Use xlang mode | true |
compatible(bool) | Enable schema evolution | xlang: true; native: false |
track_ref(bool) | Enable reference tracking | true |
max_dyn_depth(uint32_t) | Maximum nesting depth for dynamic types | 5 |
check_struct_version(bool) | Enable struct version checking | false |
Security
Security-related configuration:
- Register all structs and polymorphic implementations before deserializing untrusted payloads.
- Use
check_struct_version(true)withcompatible(false)when exact schema matching is required. - Keep
max_dyn_depth(...)as low as your model permits to reject unexpectedly deep polymorphic graphs. - Prefer concrete fields over broad polymorphic fields for untrusted input.
Related Topics
- Basic Serialization - Using configured Fory
- Xlang Serialization - xlang mode details
- Type Registration - Registering types