neuray API Programmer's Manual

Library Design

In addition to the introduction given here, the Tutorial and Example Programs explain many topics about the neuray API design.

A list of such topics can be found in the Index of Topics Explained in the Example Programs.


The neuray API follows conventional modern C++ library design principles for component software to achieve binary compatibility across shared library boundaries and future extensibility. The design provides access to the shared library through interfaces, abstract base classes with pure virtual member functions.

The global function INVALID_DOXYREF returns the main interface mi::neuraylib::INeuray that allows access to the whole library. From this interface other interfaces of the library can be accessed with the mi::neuraylib::INeuray::get_api_component() member function.

Reference counting

Interfaces are reference-counted dynamic resources that need to be released. Whenever a function returns a pointer to mi::base::IInterface or a subclass thereof, the corresponding reference counter has already been increased by 1. That is, you can use the interface pointer without worrying whether the pointer is still valid. Whenever you do not need an interface any longer, you have to release it by calling its release() method. Omitting such calls leads to memory leaks.

Handle class

To simplify your life and to relieve you from keeping track of release() calls, we offer a simple handle class mi::base::Handle. This handle class maintains a pointer semantic while supporting reference counting for interface pointers. For example, the -> operator acts on the underlying interface pointer. The destructor calls release() on the interface pointer, copy constructor and assignment operator take care of retaining and releasing the interface pointer as necessary. Note that it is also possible to use other handle class implementations, e.g., std::tr1::shared_ptr<T> (or boost::shared_ptr<T>). See Example for Starting and Shutting Down the neuray API for details.


In general, you should aim for minimal resource usage. This implies releasing interface pointers as soon as you no longer need them. When using a handle class, it can be beneficial to introduce additional { ... } blocks to enforce the destruction of the handle, and release of the corresponding interface pointer, at the end of the block.


There is an interface mi::IString representing strings. However, some methods return constant strings as a pointer to const char for simplicity. These strings are managed by the neuray API and you must not deallocate the memory pointed to by such a pointer. These pointers are valid as long as the interface from which the pointer was obtained is valid.