Getting Started
QAROS ships a native C API and an idiomatic C#/.NET binding over it. Pick your language above — the selection follows you across the whole Developer Guide. Whichever you choose, the simplest integration is genuinely simple: initialize the library, create a runtime, obtain a session, do work, tear down in reverse.
This guide is self-contained. If you want the mental model first, read Concepts; otherwise start here.
Setting up
The C SDK consists of:
qar_streaming.h— a single amalgamated header containing the complete v0 C API. It is auto-generated from the authoritative API sources on every runtime build, so the header in a given package always matches its binaries exactly. Never edit it.qar-streaming-c.dll/.so— the library your app links against or loads at runtime.- Runtime binaries — the services the library spawns/uses, in the binary
package's
bin/folder. - Examples — small, self-contained C programs in
qar-streaming-c/examples/, compiled as part of this repository so they are always valid against the current header. The Tutorials are built from them.
Static linking vs. dynamic loading
Both modes expose identical function names.
| Static / import-library linking | Dynamic loading | |
|---|---|---|
| How | Link qar-streaming-c.lib, call functions directly | Define QAR_ENABLE_DYNAMIC_LOADING, load the DLL at runtime |
| Startup dependency | DLL must be present at process start | Your app starts without QAROS; loads it on demand |
| Failure mode | Loader error dialog | You handle a bool load failure gracefully |
| Recommended for | Tools that always ship with QAROS | Plugins and apps where AR/VR is optional |
Dynamic loading is recommended for integrating into an existing application: your software keeps working on machines without QAROS installed.
// Dynamic-loading mode: one macro before the include, one macro in ONE .c file.
#define QAR_ENABLE_DYNAMIC_LOADING
#include <qar_streaming.h>
QAR_IMPLEMENT_DYNAMIC_LOADING() // exactly once per application
int main(int argc, char** argv)
{
if (not qar_library_load("path/to/qar-streaming-c.dll"))
{
// QAROS not present — run without AR/VR features
return 1;
}
// ... use the API exactly as in static mode ...
qar_library_unload();
return 0;
}
Functions are loaded from the DLL by symbol name into application-owned function tables — there is no loader struct in the ABI, so newer DLLs keep working with older applications and vice versa. Full walkthrough: Dynamic Loading tutorial.
Building the examples
# 1. Drop the QAROS binary package into ./package (see the Operator Guide's
# Installation page for the package layout).
# 2. Configure and build
cmake --preset x64-windows
cmake --build --preset x64-windows-debug
# 3. Run an example
./build/x64-windows/Debug/dynamic_loading.exe ./package/bin/qar-streaming-c.dll
The canonical program skeleton
Every QAROS application has the same shape: library init → runtime → session → work → teardown in reverse.
#include <qar_streaming.h>
int main(void)
{
// 1. Library init (process-wide, once)
QarLibraryInit lib_init = qar_library_init_default();
lib_init.enable_console_logging = true;
qar_result_log_if_error(qar_library_init(&lib_init));
// 2. Runtime create (your process's QAROS context)
QarRuntimeInit rt_init = qar_runtime_init_default();
QarRuntime* runtime = NULL;
qar_result_log_if_error(qar_runtime_create(&rt_init, &runtime));
// 3. Obtain a session: rejoin if we onboarded before, else onboard
// (see Onboarding and Sessions)
// 4. Do work: streams, panels, volumes, peers
// 5. Teardown, in reverse
qar_runtime_destroy(runtime);
qar_result_log_if_error(qar_library_destroy());
return 0;
}
Steps 3 and 4 are what the rest of this guide is about. Read API Conventions once — the API follows a handful of strict patterns in both languages, and knowing them makes every module predictable. Then continue to Onboarding and Sessions.