This example accesses the main DiCE interface, queries the API version, and then starts and shuts down the DiCE API. See the Getting Started Section for a description of how the example programs can be compiled.
The DiCE library is written in C++. It uses the mi and mi::neuraylib namespaces for its own identifiers, or the MI_NEURAYLIB_ prefix for macros.
Multiple words are concatenated with _
to form identifiers. Function names are all lower case, while types and classes start with one initial upper-case letter.
The include file mi/dice.h provides all the functionality of the DiCE API.
The mi_factory() function is the only public access point to all algorithms and data structures in the API (see Library Design for an explanation why.) The factory function tries to access the DiCE API. If the access succeeds, it returns a pointer to an instance of the main mi::neuraylib::INeuray interface. The mi_factory() function may be called only once per process.
Before you are able to call the mi_factory() function, you need to load the DiCE DSO and to locate the factory function. The convenience function load_and_get_ineuray()
abstracts these platform-dependent steps.
Note that it is not required to use load_and_get_ineuray()
. In particular in larger setups you might want to write your own code to load the DiCE DSO and to locate the factory function. In such cases, you call mi_factory() directly. For simplicity, the examples will use the convenience function load_and_get_ineuray()
instead of mi_factory().
Except for trivial classes, such as the math vector class, all classes in the DiCE API are implemented using interfaces. See Library Design for an explanation. Interfaces are created and destroyed by the DiCE API. They implement reference counting for life-time control and cheap copying operations. Interface names start with an I
prefix.
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. To simplify your life we provide 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, which means that you can use a handle to a particular interface pointer in a way very similar to the interface pointer itself. 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 the handle class has two different constructors to deal with ownership of the interface pointer. See the mi::base::Handle documentation for details.
Note that it is also possible to use other handle class implementations, e.g., std::tr1::shared_ptr<T>
(or boost::shared_ptr<T>
). In case you prefer to use such handle classes, you have to ensure that their destructor calls the release()
method of the interface pointer. This can be achieved by passing an appropriate argument as second parameter, e.g.,
The mi::neuraylib::INeuray interface is used to start and shut down the DiCE API. The API can only be used after it has been started (and before it has been shut down). Startup does not happen during the mi_factory() call because you might want to configure the behavior of the API, which has to happen before startup (see Example for Configuration of the DiCE API for details).
The status of the API can be queried using the mi::neuraylib::INeuray::get_status() method.
Finally, you have to shut down the DiCE API. At this point, you should have released all interface pointers except the pointer to the main mi::neuraylib::INeuray interface. If you are using the handle class, make sure that all handles have gone out of scope.
Source Code Location: examples/example_shared.h
Source Code Location: examples/example_start_shutdown.cpp