C API Reference
The C API Reference documents the data types, data structures, interfaces and methods in the Vuforia SDK.
API Concepts
- General
- Vuforia does not promise any ABI compatibility between releases. Developers are expected to recompile the code with the new headers. We do not support just exchanging the binaries.
- Developers are advised to follow best practices documented in our API and sample application code. As an example, developers should use the struct initializer functions such as vuConfigDefault() to initialize observer configuration instead of directly initializing these structs through aggregate initialization.
- Units
- Vuforia uses meters as unit of measurement. This means spatial attributes such as positions, distances, sizes, etc. are defined in terms of meters, unless explicitly documented otherwise.
Angles are defined in terms of degrees.
Timestamps are defined in terms of nanoseconds.
- Syntax
- All types, data structures, functions start with a Vu prefix using the following notation:
- vuFunctionName for functions and procedures
- VuType for type (e.g. public typedef, opaque type, enum, struct, etc)
- VU_VALUE for any enum values or define values
- Type
- Most objects in the Vuforia Engine API are represented by pointers (handles) to opaque struct types. The majority of functions in Vuforia Engine operate on these opaque pointers to objects. The general pattern is thereby that the opaque pointer is the first parameter for the respective functions related to this type (equivalent to the 'this' pointer in C++). The function will be prefixed with the respective type. For example a vuEngine...() function will always take a opaque pointer to a VuEngine instance as the first parameter.
- The API also contains data structures in the form of structs which are mainly used for providing configuration or for retrieving properties of the opaque types.
- For container data types such as a list, you need to use a dedicated API for creating, destroying, accessing elements, e.g. for a list containing elements of type "Object" use
- vuObjectListCreate(ObjectList** list)
- vuObjectListDestroy(ObjectList* list)
- vuObjectListGetSize(const ObjectList* list, int32_t* listSize)
- vuObjectListGetElement(const ObjectList* list, int32_t elementIndex, Object** element)
- Please be aware of padding when using a Vuforia structures directly if you want to wrap the API in another language.
- Functions
- All functions use the VU_API preprocessor macro for export and VU_API_CALL for the calling convention. Function syntax uses the following convention:
return_value vuObjectTypeAction(ObjectType* , [param])
when you want to execute the action on an object of type ObjectType.
- Common actions are Create, Destroy, Get, Set, Acquire, Release.
- Return value:
- Most functions return VuResult to indicate execution success / failure
- Some utility functions (e.g. math) will return a value that allows chaining such calls easily (e.g. mathematical expression)
- Parameters:
- First parameter is usually a handle to an object (exceptions include utility functions)
- Output parameters are at the end of the parameter list
- Please note that the API does not perform any sanity checks to catching passing NULL or invalid values (e.g. already freed memory).
- Some of the Get() functions have an associated Has() function that should be used prior to Get() to test whether there is a valid object instance to retrieve in case the returned object is optional or not yet available. If there is no valid instance, then the getter function will return VU_FAILED. For examples, see e.g. vuObservationHasPoseInfo() and vuObservationGetPoseInfo().
- Ownership
- The objects managed by Engine generally have a hierarchical ownership relation. Objects retrieved via Get() functions are owned by the object they are retrieved from.
- For example, in order to get the image data for the current camera frame, you need to first retrieve a VuCameraFrame from a VuState by calling vuStateGetCameraFrame(), and then retrieve a VuImageList from the VuCameraFrame via vuCameraFrameGetImages() which provides access the VuImage instances of the frame. The lifetime of the VuImage instances retrieved via the VuImageList will be bound to the lifetime of the VuCameraFrame instance, which in turn will be bound to the lifetime of the VuState instance. If the lifetime of the VuState ends, all pointers to objects directly or indirectly owned by the VuState instance will be invalidated throughout this ownership hierarchy and should not be accessed after this point.
- Similarly, output buffer data retrieved via Get() functions, such as strings (const char*) or general memory buffers (e.g. void*), will be bound to the lifetime of the object they have been retrieved from.
- Note that the ownership relation also extends to string or buffer pointers returned as members of non-opaque structs. For example, when retrieving information about a VuImage via VuImageInfo, the lifetime of the buffer pointer member of the VuImageInfo struct is bound to the lifetime of the VuImage instance the VuImageInfo was retrieved from.
- In general, const char* string data provided as an input parameter will be copied, meaning the buffer can be freed up again after the call. For general buffer data provided as input please refer to the documentation of the respective function on how the data will be handled.
- Objects created with vuCreate..() are owned by the application and should be explicitly destroyed with the corresponding vuDestroy..() function as soon as they are not needed any more.
- For some objects owned by the Engine instance the API provides ways to acquire an explicit reference via vuAcquire..() to keep the data beyond the usual lifetime. These objects need to be explicitly released again via a call to vuRelease..() to free up the resources.
- It is strongly recommended to explicitly destroy/release objects as soon as they are not needed any more and not to hold on to these longer than required. This is particularly important for data from the state, like e.g. frame image data, to allow Engine to free up resources internally. If the data is required for an extended amout of time, the client should instead create a copy of the data needed.
- Note that when Vuforia Engine is destroyed it will free up any resources internally and will also invalidate pointers owned by Engine. It will also invalidate pointers to some object types explicitly created/acquired by the client application, such as observers and state references, that hold on to important internal resources. In general, the client should not access any pointers to objects after Engine destruction and should explicitly destroy/release any pointers prior to destroying the Engine instance in order to avoid any resource leaks.
- See also the documentation of the respective API functions for information on ownership and lifetime.
- Versioning
- At compilation time, you can access the VU_VERSION_MAJOR | MINOR | PATCH preprocessor values defined in the VuforiaEngine.h umbrella header file. At runtime, you can query the Vuforia Engine version by calling the function vuEngineGetLibraryVersionInfo().
- Multi-threading and thread safety
- The Vuforia API is NOT thread-safe and API functions should NOT be called concurrently from multiple threads. It is the responsibility of the client code to ensure that concurrent calls from multiple threads to Vuforia API functions are synchronized. Failing to protect these API calls from concurrent access in multiple threads might result in undefined behavior including memory corruption, instability or crashes.
- Vuforia callbacks
- Vuforia Engine callbacks are executed on dedicated internal threads. Callback implementations in client code need to be synchronized with other threads in your client code. Note that Vuforia Engine uses several other threads internally to operate the AR pipeline.
- The Vuforia Engine internally synchronizes all API calls made from a client thread with the callback thread. All API calls are performed in a blocking manner and the internal state is guaranteed to be updated once control returns to user code. As a consequence, changes to the internal AR pipeline (e.g. observer manipulation via functions such as vuObserverActivate(), vu*ObserverSetTargetScale(), etc.) may take one camera frame to process until they return. API calls are executed immediately when Vuforia is not running or called from within the state handler callback on the camera thread.
- Due to the synchronous nature of the Vuforia API internals, it is possible that the Vuforia State obtained via the registered state handler or via vuEngineAcquireLatestState() may not reflect changes made during the last camera frame. Observations from an observer deactivated or destroyed during the last frame might still be reported.
- Callbacks and reentrancy
- The Vuforia API allows reentrant calls to be performed during callbacks such as the camera state handler or the Cloud Image Target observation handler, except calls controlling the Vuforia Engine's lifecycle such as vuEngineStop() or vuEngineDestroy(), as well as functions modifying the callback handler like vuEngineRegisterStateHandler(). Functions that cannot be invoked during a callback are highlighted explicitly in the respective API documentation.
- Client code also need to ensure that reentrant calls from the callback are synchronized with calls from other application threads as mentioned earlier in the section on "Multithreading and thread safety".
- Documentation
- Inline documentation is using Doxygen formatting with the C++ convention.