libivon is a real-time multi-party voice communication library. It provides a stable C ABI for maximum portability and header-only C++ wrappers for ergonomic use from C++ consumers. This reference covers the public API surface: voice sessions, client networking, audio processing, and server administration.
Headers at a Glance
All public headers live under include/libivon/public/ within each component. Include them with #include "libivon/public/...".
| Header | Purpose |
ivon_voice_session.h | High-level API — bundles client + audio into one object |
ivon_voice_session_wrapper.hpp | C++ RAII wrapper for the voice session |
ivon_voice_session_types.h | Opaque handles, enums, and config for the voice session |
ivon_client.h | Network client — connect, message, groups |
ivon_client_wrapper.hpp | C++ RAII wrapper for the client |
ivon_client_interface.hpp | Abstract C++ interface for the client |
ivon_client_types.h | Opaque handles, enums, and callbacks for the client |
ivon_audio.h | Audio processor — encode, decode, mix |
ivon_audio_wrapper.hpp | C++ RAII wrapper for the audio processor |
ivon_audio_interface.hpp | Abstract C++ interface for the audio processor |
ivon_audio_types.h | Opaque handles, enums, frame duration, and constants |
ivon_server.h | Server — accept connections, manage groups |
ivon_server_wrapper.hpp | C++ RAII wrapper for the server |
ivon_server_interface.hpp | Abstract C++ interface for the server |
ivon_server_types.h | Opaque handles, enums, and callbacks for the server |
ivon_common_types.h | Shared callback typedefs |
ivon_types.hpp | C++ value types — NegotiationError, AudioOutputFrame, enums, callbacks |
Each *_types.h header defines the opaque handles, enumerations, config structs, and callback typedefs used by the corresponding API header.
Quick Start — Voice Session (C++)
The voice session is the recommended entry point for most consumers. It wires the client and audio processor together automatically.
#include <iostream>
#include <span>
#include <vector>
bool capture_mic(float *buf, size_t n);
void play_audio(const float *buf, size_t n);
volatile bool running = true;
int main() {
session.set_pcm_source([](std::span<float> pcm_out) -> bool {
return capture_mic(pcm_out.data(), pcm_out.size());
});
session.on_tofu_verify([](const std::string &, auto, auto, auto) {
return true;
});
<< (info.
speaking ?
" started" :
" stopped")
<< " speaking\n";
});
auto result = session.connect();
if (!result) {
std::cerr << "Connect failed: " << result.error().message()
<< " — " << result.error().detail() << "\n";
return 1;
}
session.start_audio();
while (running) {
auto frame = session.audio().try_read_output(pcm.data(), pcm.size());
if (frame.valid) {
play_audio(pcm.data(),
static_cast<size_t>(frame.frame_size) * frame.channels);
}
}
session.audio().stop_speaking();
session.disconnect();
}
Consumer-facing C++ wrapper around the voice session C ABI.
Definition ivon_voice_session_wrapper.hpp:47
@ IVON_SPEAKING_MODE_VAD
Voice-activity detection.
Definition ivon_audio_types.h:44
#define IVON_AUDIO_FRAME_SIZE
Samples per channel per frame (960).
Definition ivon_audio_types.h:106
uint8_t output_channels
Output channel count: 1 = mono, 2 = stereo.
Definition ivon_audio_wrapper.hpp:60
uint16_t server_port
Server TCP port.
Definition ivon_client_wrapper.hpp:54
std::string server_address
Server hostname or IP address to connect to.
Definition ivon_client_wrapper.hpp:53
std::string client_id
Unique identifier for this client in the session.
Definition ivon_client_wrapper.hpp:55
Combined configuration for the voice session.
Definition ivon_voice_session_wrapper.hpp:52
AudioWrapper::Config audio
Definition ivon_voice_session_wrapper.hpp:57
ClientWrapper::Config client
Definition ivon_voice_session_wrapper.hpp:54
std::string voice_group_id
Definition ivon_voice_session_wrapper.hpp:60
Speaking state change with client ID mapping.
Definition ivon_voice_session_wrapper.hpp:73
bool speaking
True = started speaking, false = stopped speaking.
Definition ivon_voice_session_wrapper.hpp:77
std::string client_id
Human-readable client name (empty if sender is unknown)
Definition ivon_voice_session_wrapper.hpp:75
Quick Start — Voice Session (C)
#include <stdio.h>
int capture_mic(float *buf, int n);
void play_audio(const float *buf, int n);
volatile int running = 1;
static int pcm_source(float *pcm_out, int frame_size, void *user_data) {
(void)user_data;
return capture_mic(pcm_out, frame_size);
}
const uint8_t *stored, void *user_data) {
(void)server_id; (void)result; (void)server_key;
(void)stored; (void)user_data;
return 1;
}
int main(void) {
if (!session) { return 1; }
fprintf(stderr,
"Connect failed: %s\n", r.
message);
return 1;
}
while (running) {
}
}
}
void ivon_audio_stop_speaking(ivon_audio_t audio)
Stop speaking (PTT released).
void ivon_audio_config_destroy(ivon_audio_config_t config)
Destroy an audio configuration handle. NULL is a safe no-op.
ivon_audio_config_t ivon_audio_config_create(void)
Create a new audio configuration with sane defaults.
void ivon_audio_config_set_output_channels(ivon_audio_config_t config, uint8_t channels)
Set output channel count: 1 = mono, 2 = stereo.
ivon_audio_output_frame_t ivon_audio_try_read_output(ivon_audio_t audio, float *pcm_out, size_t max_samples)
Try to read a mixed output frame (copy-out).
struct ivon_audio * ivon_audio_t
C ABI types for the libivon audio processor.
Definition ivon_audio_types.h:30
struct ivon_audio_config * ivon_audio_config_t
Opaque audio processor configuration handle.
Definition ivon_audio_types.h:122
void ivon_client_config_destroy(ivon_client_config_t config)
Destroy a client configuration handle. NULL is a safe no-op.
ivon_client_config_t ivon_client_config_create(void)
Create a new client configuration with sane defaults.
void ivon_client_config_set_server_address(ivon_client_config_t config, const char *address)
Set the server address (e.g. "127.0.0.1"). The string is copied.
void ivon_client_set_on_tofu_verify(ivon_client_t client, ivon_tofu_verify_fn callback, void *user_data)
Set the TOFU key verification callback.
void ivon_client_config_set_port(ivon_client_config_t config, uint16_t port)
Set the server port (default 9129).
void ivon_client_config_set_client_id(ivon_client_config_t config, const char *client_id)
Set the client identifier. The string is copied.
enum ivon_tofu_verify_result ivon_tofu_verify_result_t
TOFU verification results (mirrors TofuVerifyResult).
#define IVON_PUBLIC_KEY_SIZE
PUBLIC_KEY_SIZE from the C++ side.
Definition ivon_client_types.h:205
struct ivon_client_config * ivon_client_config_t
Opaque client configuration handle.
Definition ivon_client_types.h:132
struct ivon_client * ivon_client_t
C ABI types for the libivon client.
Definition ivon_client_types.h:32
void ivon_voice_session_config_destroy(ivon_voice_session_config_t config)
Destroy a voice session configuration. NULL is a safe no-op.
void ivon_voice_session_config_set_client(ivon_voice_session_config_t config, ivon_client_config_t client)
Set the client sub-configuration.
ivon_client_t ivon_voice_session_client_handle(ivon_voice_session_t session)
Get the underlying client handle.
void ivon_voice_session_destroy(ivon_voice_session_t session)
Destroy a voice session and free all resources.
ivon_connect_result_t ivon_voice_session_connect(ivon_voice_session_t session)
Connect to the server (blocking).
ivon_voice_session_t ivon_voice_session_create(ivon_voice_session_config_t config)
Create a new voice session.
void ivon_voice_session_start_speaking(ivon_voice_session_t session, ivon_speaking_mode_t mode)
Start speaking (PTT activated).
ivon_audio_t ivon_voice_session_audio_handle(ivon_voice_session_t session)
Get the underlying audio processor handle (non-owning).
void ivon_voice_session_config_set_audio(ivon_voice_session_config_t config, ivon_audio_config_t audio)
Set the audio sub-configuration.
ivon_voice_session_config_t ivon_voice_session_config_create(void)
Create a new voice session configuration with defaults.
void ivon_voice_session_set_pcm_source(ivon_voice_session_t session, ivon_audio_pcm_source_fn callback, void *user_data)
Set the PCM source callback for local audio capture.
void ivon_voice_session_disconnect(ivon_voice_session_t session)
Disconnect from the server.
void ivon_voice_session_start_audio(ivon_voice_session_t session)
Start the audio processor (tick coordinator + worker threads).
void ivon_voice_session_config_set_voice_group_id(ivon_voice_session_config_t config, const char *group_id)
Set the voice group to auto-join after connection.
struct ivon_voice_session * ivon_voice_session_t
C ABI types for the libivon voice session helper.
Definition ivon_voice_session_types.h:36
struct ivon_voice_session_config * ivon_voice_session_config_t
Opaque voice session configuration handle.
Definition ivon_voice_session_types.h:50
Mixed audio output frame (copy-out).
Definition ivon_audio_types.h:214
int valid
Non-zero if frame data is valid.
Definition ivon_audio_types.h:215
uint8_t channels
Number of channels in the output.
Definition ivon_audio_types.h:217
int frame_size
Samples per channel actually written.
Definition ivon_audio_types.h:216
Result of a connect() call.
Definition ivon_client_types.h:141
int success
Non-zero on success.
Definition ivon_client_types.h:142
const char * message
Human-readable error message (static lifetime, do not free).
Definition ivon_client_types.h:147
Quick Start — Server
#include <iostream>
#include <thread>
int main() {
cfg.
groups = {
"voice",
"team-a",
"team-b"};
std::thread stopper([&server] {
wait_for_shutdown_signal();
server.stop();
});
server.run();
stopper.join();
}
Server configuration.
Definition ivon_server_wrapper.hpp:55
struct ivon::ServerWrapper::Config::@1 key_files
Key files — set ONE of raw_keys or key_files.
bool require_password
Require password from clients.
Definition ivon_server_wrapper.hpp:62
std::string public_key_file
Path to public key file.
Definition ivon_server_wrapper.hpp:83
uint16_t port
Listen port.
Definition ivon_server_wrapper.hpp:58
std::string password
Expected password.
Definition ivon_server_wrapper.hpp:63
std::string private_key_file
Path to private key file.
Definition ivon_server_wrapper.hpp:84
std::string address
Listen address.
Definition ivon_server_wrapper.hpp:57
std::vector< std::string > groups
Groups created at startup.
Definition ivon_server_wrapper.hpp:66
RAII wrapper around the libivon server C ABI.
Definition ivon_server_wrapper.hpp:43
ServerWrapper callbacks (admission gates, auth hooks, connect/disconnect events) can be set before or after construction. Post-construction calls update the live server handle atomically:
server.on_client_connected([](const std::string &client_id, uint64_t session_id) {
std::cout << client_id << " connected (session " << session_id << ")\n";
});
server.on_connection_admission([](const std::string &ip, uint16_t port) -> bool {
return ip != "10.0.0.1";
});
For the C API, use ivon_server_config_set_on_*() on the config handle before calling ivon_server_create():
void ivon_server_config_destroy(ivon_server_config_t config)
Destroy a server configuration handle.
void ivon_server_config_set_on_client_disconnected(ivon_server_config_t config, ivon_server_client_disconnected_fn callback, void *user_data)
Set the client disconnected event callback.
void ivon_server_run(ivon_server_t server)
Run the server (blocks until stop() is called).
ivon_server_t ivon_server_create(ivon_server_config_t config)
Create a new server instance from a populated config.
ivon_server_config_t ivon_server_config_create(void)
Create a new server configuration handle.
void ivon_server_destroy(ivon_server_t server)
Destroy a server instance and free all resources.
void ivon_server_config_add_group(ivon_server_config_t config, const char *group_id)
Add a group to be created at server startup.
void ivon_server_config_set_on_client_connected(ivon_server_config_t config, ivon_server_client_connected_fn callback, void *user_data)
Set the client connected event callback.
void ivon_server_config_set_address(ivon_server_config_t config, const char *address)
Set the listening address (default "0.0.0.0").
void ivon_server_config_set_port(ivon_server_config_t config, uint16_t port)
Set the listening port (default 9129).
struct ivon_server * ivon_server_t
C ABI types for the libivon server.
Definition ivon_server_types.h:32
struct ivon_server_config * ivon_server_config_t
Opaque handle to a server configuration (builder pattern).
Definition ivon_server_types.h:35
Architecture
Threading Model
The library creates internal worker threads. Callbacks are invoked from these threads — they must be thread-safe and non-blocking.
| Thread | Fires |
| Decoder workers (N) | on_speaking_event, on_pre_dsp |
| Pipeline workers (N) | on_post_spatial, on_post_mix |
| Encoder drain worker | (internal — drains encoded packets) |
| IO threads (server) | All server gate/event callbacks |
| Client IO thread | on_client_message, on_client_joined/left, group callbacks |
Audio Format
| Property | Value |
| Sample rate | 48 000 Hz |
| Frame duration | 20 ms default; configurable via frame_duration (2.5, 5, 10, 20, 40 ms) |
| Frame size | 960 samples/channel at 20 ms; query at runtime with pcm_frame_size() / ivon_audio_frame_size() |
| Capture format | Mono float (PCM source callback) |
| Output format | Interleaved float (try_read_output) |
| Codec | Opus |
| Max output channels | 8 (default 2 — stereo); query with output_channels() / ivon_audio_output_channels() |
Object Ownership
All wrappers are RAII, move-only, non-copyable. The destructor stops the processor/server/client and frees all resources. Passing NULL to any C _destroy() function is a safe no-op.
The voice session owns its internal client and audio handles. Access the client handle via client_handle() for chat/presence callbacks, but do not destroy it or replace the audio/group callbacks that the session manages internally.
Standalone Client + Audio (Advanced)
For full control over the client and audio processor independently:
client.on_fanout_data([&audio](const std::string &group_id, uint64_t sender_id,
uint64_t seq, const unsigned char *data, size_t len) {
audio.submit_packet(sender_id, data, len);
});
std::array<unsigned char, 2048> pkt;
size_t n = audio.try_read_packet(pkt.data(), pkt.size());
if (n > 0) {
client.send_group_data("voice", pkt.data(), n);
}
Consumer-facing C++ wrapper around the libivon audio C ABI.
Definition ivon_audio_wrapper.hpp:44
Consumer-facing C++ wrapper around the libivon C ABI.
Definition ivon_client_wrapper.hpp:47
Configuration for creating an audio processor.
Definition ivon_audio_wrapper.hpp:52
uint8_t decoder_workers
Number of Opus decoder worker threads.
Definition ivon_audio_wrapper.hpp:57
Configuration for creating a client (mirrors ivon_client_config_t).
Definition ivon_client_wrapper.hpp:52
This is what the voice session does internally. Use this pattern when you need custom routing, multiple groups, or separate lifecycle control.
DSP Pipeline
The audio processor exposes three hook points in the decode → mix pipeline. Each callback receives a writeable PCM buffer — modify in-place to apply effects. Return IVON_DSP_ACTION_STOP to discard the frame.
Opus decode
│
▼
┌──────────────────┐
│ on_pre_dsp │ Mono per-sender (frame_size float samples)
│ (CONTINUE/STOP) │ Use for: per-speaker gain, noise gate, AGC
└──────────────────┘
│
▼
Channel expansion (mono → stereo/surround)
│
▼
┌──────────────────┐
│ on_post_spatial │ Expanded per-sender (frame_size × channels floats)
│ (CONTINUE/STOP) │ Use for: spatial positioning, HRTF, panning
└──────────────────┘
│
▼
Additive mix (all senders summed)
│
▼
┌──────────────────┐
│ on_post_mix │ Final mix (frame_size × channels floats)
│ (CONTINUE/STOP) │ Use for: limiter, master EQ, recording
└──────────────────┘
│
▼
Output ring buffer → try_read_output()
frame_size is pcm_frame_size() (C++) or ivon_audio_frame_size() (C). The default is 960 (20 ms at 48 kHz), but the server may negotiate a different value.
if (rms < threshold) {
}
});
@ IVON_DSP_ACTION_CONTINUE
Continue to next pipeline stage.
Definition ivon_audio_types.h:63
enum ivon_dsp_action ivon_dsp_action_t
DSP callback return value — controls pipeline continuation.
Context for pre-DSP callbacks (mono per-sender).
Definition ivon_audio_types.h:172
int frame_size
Samples per channel.
Definition ivon_audio_types.h:178
float * pcm
Mono PCM buffer (writeable)
Definition ivon_audio_types.h:177
Error Handling
| Layer | C | C++ |
| Object creation | Returns NULL | Throws std::runtime_error |
| Connection | ivon_connect_result_t with error codes and message | expected_void<NegotiationError> |
| Group operations | Status enum in result struct | Same struct passed through |
| Async operations | int success in completion callback | std::function<void(bool)> |
Connection errors carry both a negotiation code (protocol/auth level) and a connection code (transport level). Check is_connection_error() to distinguish:
auto result = session.connect();
if (!result) {
auto &err = result.error();
if (err.is_connection_error()) {
} else {
}
std::cerr << err.message() << "\n" << err.detail() << "\n";
}
TOFU Key Verification
The client uses Trust-On-First-Use for server identity. The TOFU callback receives the server's public key and a result indicating whether the key is new, trusted, or changed:
| Result | Meaning | Recommended action |
IVON_TOFU_TRUSTED | Key matches stored key | Accept |
IVON_TOFU_NEW_KEY | First connection, no stored key | Prompt user or accept |
IVON_TOFU_KEY_CHANGED | Key differs from stored | Warn user — possible MITM |
IVON_TOFU_VERIFICATION_ERROR | Key verification failed | Reject |
session.on_tofu_verify([](const std::string &server_id,
const std::array<uint8_t, ivon::PUBLIC_KEY_SIZE> &server_key,
const std::optional<std::array<uint8_t, ivon::PUBLIC_KEY_SIZE>> &stored_key) -> bool {
std::cerr << "WARNING: Server key changed for " << server_id << "\n";
return false;
}
return true;
});
TofuVerifyResult
Result of TOFU (Trust-On-First-Use) key verification.
Definition ivon_types.hpp:325
@ key_changed
Server seen before but key has changed.
Server Authentication Pipeline
The server supports a multi-stage admission pipeline. Each gate is a callback that returns true (accept) or false (reject):
TCP connect
│
▼
┌────────────────────────┐
│ on_connection_admission│ Gate: IP/port filtering
└────────────────────────┘
│
▼
┌────────────────────────┐
│ on_client_id_check │ Gate: validate client ID format/uniqueness
└────────────────────────┘
│
▼
┌────────────────────────┐
│ on_password_validate │ Gate: custom password check (if require_password)
└────────────────────────┘
│
▼
┌────────────────────────┐
│ on_client_approve │ Gate: final approval before visibility
└────────────────────────┘
│
▼
┌────────────────────────┐
│ on_client_connected │ Event: client is now registered
└────────────────────────┘
All gates are optional. If a gate callback is not set, the stage is automatically approved.
Configuration Reference
Audio (<tt>ivon_audio_config_t</tt> / <tt>AudioWrapper::Config</tt>)
| Field | Default | Description |
frame_duration | IVON_FRAME_DURATION_20_MS | Codec frame duration (2.5, 5, 10, 20, 40 ms) |
packet_pool_chunks | 4 | Packet pool chunks (1024 buffers each) |
frame_pool_chunks | 4 | Frame pool chunks (256 frames each) |
decoder_workers | 2 | Decoder thread count |
jitter_depth | 2 | Frames to buffer before playback (0 = bypass) |
pipeline_workers | 2 | Pipeline (mix) thread count |
output_channels | 2 | Output channels (1=mono, 2=stereo, up to 8) |
output_buffer_frames | 200 | Output ring buffer capacity in frames |
encoder_bitrate | 64000 | Opus target bitrate (bps) |
encoder_fec | 1 | Enable Opus forward error correction |
encoder_fec_loss_percent | 5 | Expected packet loss hint for FEC tuning |
encoder_complexity | 5 | Opus complexity (0–10, higher = better quality) |
Client (<tt>ivon_client_config_t</tt> / <tt>ClientWrapper::Config</tt>)
| Field | Default | Description |
server_address | "127.0.0.1" | Server hostname or IP |
server_port | 9129 | Server TCP port |
client_id | — | Unique identifier for this client |
key_store_path | NULL | Path to TOFU key store file (NULL = in-memory) |
sync_timeout_seconds | 30 | Initial sync timeout (0 = infinite) |
Server (<tt>ivon_server_config_t</tt> / <tt>ServerWrapper::Config</tt>)
| Field | Default | Description |
address | "0.0.0.0" | Listen address |
port | 9129 | Listen port |
network_interface | — | Bind to specific interface (Linux only) |
num_threads | 1 | IO thread count |
require_password | false | Require client authentication |
password | — | Expected password |
max_password_attempts | 3 | Attempts before rejection |
groups | — | Groups created at startup |
fanout_base_port | 10300 | Base UDP port for audio multicast |
fanout_advertise_address | "127.0.0.1" | Address advertised to clients |
key_rotation_on_leave | true | Rotate group keys when members leave |
key_rotation_debounce_ms | 1000 | Debounce interval for key rotation |
key_rotation_interval_ms | 0 | Periodic key rotation (0 = disabled) |
Voice Session (<tt>ivon_voice_session_config_t</tt> / <tt>VoiceSessionWrapper::Config</tt>)
| Field | Default | Description |
client | — | Nested client configuration |
audio | — | Nested audio configuration |
voice_group_id | NULL | Auto-join this group after connect |
poll_interval_ms | 10 | Worker drain interval (ms) |
Statistics
Both the audio processor and voice session expose runtime statistics:
auto stats = session.get_audio_stats();
stats.current_tick;
stats.max_drift_us;
stats.dropped_ticks;
stats.packets_decoded;
stats.fec_recovered;
stats.plc_frames;
stats.silence_frames;
stats.packets_encoded;
API Versioning
Each subsystem has compile-time and runtime version macros/functions:
#if IVON_AUDIO_API_VERSION_MAJOR >= 2
#endif
int ivon_audio_api_version_major(void)
Get the major version of the audio C ABI at runtime.
int ivon_audio_api_version_minor(void)
Get the minor version of the audio C ABI at runtime.
The C++ wrappers delegate to the same C ABI and share the version numbers.
Dynamic Loader (Runtime Loading)
Each profile generates a loader header that allows consumers to load the shared library at runtime via dlopen/LoadLibrary instead of linking against it at build time. This is useful for plugin architectures, optional dependencies, or applications that want to ship without bundling the .so.
The generated loader header provides:
- Function-pointer typedefs for every exported C function
- A global vtable struct populated at load time
- Platform-aware
dlopen/LoadLibrary open/close functions
- Inline trampolines that match the original symbol names, so existing code compiles unchanged
Loader-Only Install
Each profile has a dedicated _loader install component that installs the loader header, all type headers, and the C++ wrapper headers — but not the shared library:
$ cmake --install build --component libivon_client_loader
$ cmake --install build --component libivon_server_loader
$ cmake --install build --component libivon_audio_loader
This gives consumers everything they need to compile against the API without requiring the .so at build time.
CMake Integration
In-tree targets can link against the loader INTERFACE target instead of the shared library:
target_link_libraries(my_app PRIVATE libivon_client_loader_target)
This target automatically provides:
- Include directories for type headers and the generated loader header
- The platform
dl library on Linux
- The
LIBIVON_USE_CLIENT_LOADER compile definition, which tells the C++ wrappers to route through the loader trampolines instead of linked symbols
C++ Wrapper Compatibility
The C++ wrappers (ClientWrapper, AudioWrapper, VoiceSessionWrapper, ServerWrapper) work transparently in loader mode. When the LIBIVON_USE_<PROFILE>_LOADER define is active, the wrappers include the loader header instead of the C API header. Since the loader's inline trampolines provide the same symbol names as the linked library, no wrapper code changes are needed.
Usage (C)
Include the generated loader header directly. It provides the loader open/close functions and inline trampolines for every C API function. No library linking is required at build time — only -ldl on Linux:
$ gcc -I/path/to/includes/libivon my_app.c -ldl -o my_app
#define LIBIVON_CLIENT_LOADER_H_MAIN
#include "libivon/ivon_client_loader.h"
int main(void) {
if (ivon_client_loader_open(NULL) != 0)
return 1;
ivon_client_loader_close();
return 0;
}
ivon_client_t ivon_client_create(ivon_client_config_t config)
Create a new client instance.
void ivon_client_destroy(ivon_client_t client)
Destroy a client instance and free all associated resources.
Usage (C++ with Wrapper)
Define LIBIVON_USE_CLIENT_LOADER before including the wrapper header. This tells the wrapper to pull in the loader header instead of the normal C API header, making the loader open/close functions and all API trampolines available:
Using a compile argument:
$ g++ -DLIBIVON_USE_CLIENT_LOADER -I/path/to/includes/libivon my_app.cpp -ldl -o my_app
Or inline:
#define LIBIVON_USE_CLIENT_LOADER
int main() {
if (ivon_client_loader_open(nullptr) != 0)
return 1;
{
cfg.server_address = "127.0.0.1";
cfg.server_port = 9129;
cfg.client_id = "my_app";
}
ivon_client_loader_close();
return 0;
}
Note: If using the libivon CMake build tree, linking against libivon_client_loader_target sets LIBIVON_USE_CLIENT_LOADER, the include paths, and -ldl automatically — no manual flags needed.