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 using const char*.

  • Use A3DSDKLoadLibraryW() if you wish to specify the library path using const 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() and A3DSDKUnloadLibrary().

  • 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.