2. Initializing HOOPS Exchange
This document presents you how to load and initialize HOOPS Exchange in your project to get ready for using it.
Ensure you have correctly configured your project before your go through this page.
HOOPS Exchange is a C API provided using a set of header files and binaries. The main binary file is a shared library called A3DLIBS.dll, libA3DLIBS.so or A3DLIBS.dylib according to your operating system.
In C there are two ways of loading a shared library. Either by linking against it when building your application or by manually loading it at runtime and retrieving its functions using system calls such as LoadLibrary with Windows or dlopen with GNU compilers. The latter is called explicit load and this is how HOOPS Exchange is used.
Include Exchange Headers
In your program, the source file that contains the initialization code for HOOPS Exchange must include a specific header file:
#include <A3DSDKLoader.h>
It is important that only a single source file is in charge of loading HOOPS Exchange. This file must also be the only to include A3DSDKLoader.h in your project.
The remaining files of your project can include the other source files individually, such as A3DSDKConvert.h or use the one-fit-all A3DSDKIncludes.h that will include the entire API headers.
Note
For Linux and macOS developpers:
HOOPS Exchange uses dynamic loading during its execution. If you are using HOOPS Exchange on a Linux or macOS platform, you must configure your compiler for this requirement. This means defining the HAVE_DLFCN_H preprocessor flag and linking against DLFCN using the -ldl linker option.
Loading the Library
When you load the library, you instruct the system to load the shared object file and set all function pointers to their respective values.
This is done by calling A3DSDKLoadLibrary()
.
This function exists in two versions :
Use
A3DSDKLoadLibraryA()
if you wish to specify the library path usingconst char*
.Use
A3DSDKLoadLibraryW()
if you wish to specify the library path usingconst wchar_t*
.A3DSDKLoadLibrary()
is an alias to either the first or the second function above according to if the macro_UNICODE
is respectively set or unset.
In any case, the value of the sole parameter for A3DSDKLoadLibrary()
is the path to the folder containing the shared library: A3DLIBS.dll on Windows, A3DLIBS.so on Linux and Android, or A3DLIBS.dylib on macOS.
A3DBool loaded = A3DSDKLoadLibraryA(PATH_TO_A3DLIBS_DIR);
if(loaded) {
// HOOPS Exchange Loaded
}
Providing the License
Now that all the functions are loaded, the very first function to call is A3DLicPutUnifiedLicense()
.
This function provides the license to the library, which is required for any other calls to the API.
A3DStatus result = A3DLicPutUnifiedLicense(HOOPS_LICENSE);
if(result == A3D_SUCCESS) {
// License provided
}
If any call to the API is done without a valid license set first, the function returns A3D_INVALID_LICENSE.
This error code is also returned by A3DLicPutUnifiedLicense()
when given an invalid license key.
Initializing the Library
This is a library-side operation where HOOPS Exchange performs some internal initializations.
To initialize the library, call A3DDllInitialize()
.
The expected parameter values are the major and minor version number of the API to initialize.
By default you can use A3D_DLL_MAJORVERSION
and A3D_DLL_MINORVERSION
to specify the same version as your header files.
This function returns A3D_SUCCESS
if everything went well.
A3DStatus result = A3DDllInitialize(A3D_DLL_MAJORVERSION, A3D_DLL_MINORVERSION);
if(result == A3D_SUCCESS) {
// HOOPS Exchange initialized
}
Initializing is done once. If several programs load the same HOOPS Exchange binaries, the initialization is shared.
As a convenience, HOOPS Exchange provides a function to check if the library has already been initialized: A3DDllIsInitialized()
.
Terminating the Library
When your application is finished with HOOPS Exchange, the library must be notified so that it can dispose any used resources, which is accomplished by calling A3DDllTerminate()
.
Just as with A3DDllInitialize()
, A3DDllTerminate()
must be called once per application, and every call to A3DDllInitialize()
should be paired with a call to A3DDllTerminate()
.
A3DDllTerminate();
Unloading the Library
Unloading the library is a client-side operation where all function pointers are reset to 0 and the library file is unloaded.
The function to call is A3DSDKUnloadLibrary()
and it is a client-side operation.
A3DSDKUnloadLibrary();
Code Example
The code below is a minimal yet complete working example that illustrates how to initialize HOOPS Exchange from any C client application.
#define INITIALIZE_A3D_API
#include <A3DSDKIncludes.h>
int main(int argc, char* argv[])
{
// Load the library
A3DBool loaded = A3DSDKLoadLibraryA(PATH_TO_A3DLIBS_DIR);
assert(loaded);
// We are responsible for calling 'initialize' and 'terminate' if the
// library is not already initialized
A3DBool must_initialize = !A3DDllIsInitialized();
if(must_initialize) {
A3DStatus result = A3DLicPutUnifiedLicense(HOOPS_LICENSE);
assert(result == A3D_SUCCESS);
result = A3DDllInitialize(A3D_DLL_MAJORVERSION, A3D_DLL_MINORVERSION);
assert(result == A3D_SUCCESS);
}
// HOOPS Exchange ready to use!
if(must_initialize) {
A3DDllTerminate();
}
// Unload the library
A3DSDKUnloadLibrary();
return EXIT_SUCCESS;
}
The INITIALIZE_A3D_API Macro
A3DSDKLoader.h is a special-purpose header file that effectively includes A3DSDKIncludes.h but also:
Provides
A3DSDKLoadLibrary()
andA3DSDKUnloadLibrary()
.Defines all function pointers.
It is also possible to include the loader by defining the INITIALIZE_A3D_API
macro with A3DSDKIncludes.h.
Thus:
#define INITIALIZE_A3D_API
#include <A3DSDKIncludes.h>
Is the same thing as:
#include <A3DSDKLoader.h>
In your application, it is important that one source file only includes A3DSDKLoader.h. Since the function pointers are defined in this source file (or compilation unit), having this include in more than one file will result in multiple-definition errors.
Special Rules
Parasolid Bridge and iOS
HOOPS Exchange provides an extension library called the HOOPS Parasolid Bridge. This library is able to translate models back and forth between HOOPS Exchange and a Parasolid session. For more information, see HOOPS Exchange for Parasolid Developers.
On iOS, HOOPS Exchange is provided as a static library . Therefore, functions related to the Parasolid Bridge are statically linked in the application, regardless of whether you use them or not. By default the Parasolid Bridge is considered as not used. All functions are then replaced with placeholders to avoid linker issues with your compiler.
When you want to use HOOPS Exchange along with the Parasolid Bridge, you must define an additional macro along with INITIALIZE_A3D_API: A3DAPI_NO_IOS_HEPB_STUB. This will remove the placeholder functions from your build and avoid double definitions upon linking with libhepb.a:
#define A3DAPI_NO_IOS_HEPB_STUB
#include <A3DSDKLoader.h>
// HOOPS Exchange Initialization
This restriction is only applicable to iOS builds since this is the only platform where Parasolid is statically linked.
The HOOPSExchangeLoader
Class
If your client application uses C++, you may use the HOOPSExchangeLoader
class.
This encapsulation structure brings C++ RAII principle into the HOOPS Exchange loading operation.
During the lifetime of a HOOPSExchangeLoader
instance, HOOPS Exchange is guaranteed to be initialized.
Once the instance goes out of scope the library is automatically disposed.
Thus, any call to HOOPS Exchange function must be done within the lifetime of the HOOPSExchangeLoader
instance.
See File-to-File Translation to know more about how to use HOOPSExchangeLoader
.