###########################
Initializing HOOPS Exchange
###########################

.. toctree::
   :hidden:

   /extension

This guide explains how to load and initialize HOOPS Exchange in your project for use.
Ensure that you have already configured your project as shown in the previous tutorial.

HOOPS Exchange is a library used via a C API, provided as header files and binaries.
The main binary file is a shared library named *A3DLIBS.dll*, *libA3DLIBS.so*, or *A3DLIBS.dylib*, depending on your operating system.
For iOS, it is a static library named A3DLIBS.a.

To load the library in C, you can either link against it during the application build or load it manually at runtime using system calls like LoadLibrary (Windows) or dlopen (GNU compilers).
HOOPS Exchange uses the explicit load method.

Include Exchange Headers
========================

In your program, the source file responsible for initializing HOOPS Exchange must include the header file A3DSDKLoader.h.
Only one source file should load HOOPS Exchange, and it should include A3DSDKLoader.h.
Other project files can include individual source files like A3DSDKConvert.h or use the one-fit-all A3DSDKIncludes.h to include the entire API.

Note for Linux and macOS developers: HOOPS Exchange uses dynamic loading.
If you're using HOOPS Exchange on Linux or macOS, ensure your compiler is configured with the ``HAVE_DLFCN_H`` preprocessor flag and linked against DLFCN using the ``-ldl`` linker option.

Loading the Library
===================

To load the library, call the function A3DSDKLoadLibrary with the path to the library's folder. For example:

.. code-block:: c

   A3DBool loaded = A3DSDKLoadLibraryA(PATH_TO_A3DLIBS_DIR);

   if (loaded) {
       // HOOPS Exchange Loaded
   }

Providing the License
======================

After loading the library, the first function to call is ``A3DLicPutUnifiedLicense()``.
This function provides the required license key for the library to function:

.. code-block:: c

   A3DStatus result = A3DLicPutUnifiedLicense(HOOPS_LICENSE);

   if (result == A3D_SUCCESS) {
       // License provided
   }

``HOOPS_LICENSE`` is a C-style string that represents your license key.
It is also the name of the C macro that expands to this string if you have downloaded and included **hoops_license.h**.

If any API call is made without a valid license, it returns A3D_INVALID_LICENSE.

Initializing the Library
========================

Initialization of HOOPS Exchange is a library-side operation where internal initializations are performed.
Call ``A3DDllInitialize()`` with the major and minor version numbers. 
Use ``A3D_DLL_MAJORVERSION`` and ``A3D_DLL_MINORVERSION`` to specify the same version as your header files. 
For example:

.. code-block:: c

   A3DStatus result = A3DDllInitialize(A3D_DLL_MAJORVERSION, A3D_DLL_MINORVERSION);

   if (result == A3D_SUCCESS) {
       // HOOPS Exchange initialized
   }

Initializing is a one-time operation.
If multiple programs load the same HOOPS Exchange binaries, the initialization is shared.
The function ``A3DDllIsInitialized()`` checks if the library has already been initialized.

Terminating the Library
=======================

When your application is finished with HOOPS Exchange, call ``A3DDllTerminate()`` to dispose of any used resources.
This should be called once per application and should be paired with a call to ``A3DDllInitialize()``.

Unloading the Library
=====================

To unload the library, use ``A3DSDKUnloadLibrary()``. This resets all function pointers to 0 and unloads the library file.

.. code-block:: c

   A3DSDKUnloadLibrary()

Code Example
============

Here's a minimal working example in C that demonstrates how to initialize HOOPS Exchange:

.. code-block:: c

   #define INITIALIZE_A3D_API
   #include <A3DSDKIncludes.h>
   #include <hoops_license.h>

   int main(int argc, char* argv[])
   {
       // Load the library
       A3DBool loaded = A3DSDKLoadLibraryA(PATH_TO_A3DLIBS_DIR);
       assert(loaded);

       // Initialize and terminate if not already done
       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 is included to provide necessary functions. Remember to include it in only one source file to avoid multiple-definition errors.

Special Rules
=============

For iOS builds, HOOPS Exchange provides the HOOPS Parasolid Bridge as an extension library. 
It allows translation between HOOPS Exchange and Parasolid.
When using HOOPS Exchange along with the Parasolid Bridge on iOS, define the ``A3DAPI_NO_IOS_HEPB_STUB`` macro to avoid issues with linker errors.

.. code-block:: c

   #define A3DAPI_NO_IOS_HEPB_STUB
   #include <A3DSDKLoader.h>

   // HOOPS Exchange Initialization

The `A3DSDKLoader.h` header file provides functions and defines function pointers. 
Make sure to include it in only one source file to avoid errors.

Extensions, Experimental and Deprecated Features
================================================

Some functions of HOOPS Exchange are not loaded by default and need to be explicitely enabled.
For more information, see :doc:`/extension`.

HOOPSExchangeLoader Class
=========================

For C++ applications, you can use the ``HOOPSExchangeLoader`` class to simplify HOOPS Exchange initialization and disposal.
The class ensures that HOOPS Exchange is initialized during its lifetime and is disposed of automatically when the instance goes out of scope.

See the tutorial :doc:`/tutorials/c/file-to-file-translation` (:doc:`C </tutorials/c/file-to-file-translation>`, :doc:`C# </tutorials/cs/file-to-file-translation>`) for more information on using the ``HOOPSExchangeLoader`` class in C.


