###########
C# Bindings
###########

The C# Bindings layer provides seamless access to the HOOPS Exchange C API, ensuring developers can use the API effectively in a C# environment.
This *Direct* API is defined within the ``Exchange.Direct`` namespace and its definitions are located in the following files:

:ref:`cs_bindings_structs`
   Direct Memory Layout Compatibility;

:ref:`cs_bindings_api`
   1:1 Mapping to the C API;

:ref:`cs_bindings_constants` and :ref:`cs_bindings_enums`
   Predefined values for communicating with HOOPS Exchange API.

:ref:`cs_bindings_types`
   Base numeric types corresponding to C API :ref:`api_typedefs`.


.. _cs_bindings_structs:

Structures
==========

Bindings to the C structures are provided using `C# structs <https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/struct>`__.
All C# structures have the same name as their C counterparts and are located inside the ``Direct`` namespace.

All fields of a structure are initialized with the default values of their respective types.
Since HOOPS Exchange requires specific values, use ``API.Initialize`` to prepare the structure:

.. tabs::

   .. tab:: C#

      .. code-block:: cs

         A3DRWParamsExportXMLData export_params;
         API.Initialize(out export_params);
   
         export_params.m_bExportMetadata                   = true;
         export_params.m_bExportTransformations            = true;
         export_params.m_bExportColorMaterial              = true;
         export_params.m_bExportProductInformationByFormat = false;
         
   .. tab:: C

      .. code-block:: c

         A3DRWParamsExportXMLData export_params = A3D_MAKE_DATA(A3DRWParamsExportXMLData);
         
         export_params.m_bExportMetadata                   = A3D_TRUE;
         export_params.m_bExportTransformations            = A3D_TRUE;
         export_params.m_bExportColorMaterial              = A3D_TRUE;
         export_params.m_bExportProductInformationByFormat = A3D_FALSE;

To see how numeric types are mapped between C and C#, refer to :ref:`cs_bindings_types`.
See also :doc:`utils` about manipulating C-style arrays.

The C# structures ensure a direct mapping to their C equivalent.
Thus, all structures are defined with `LayoutKind.Sequential <https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.layoutkind?view=net-9.0#system-runtime-interopservices-layoutkind-sequential>`__ and `CharSet.Ansi <https://learn.microsoft.com/en-us/dotnet/api/system.runtime.interopservices.structlayoutattribute.charset?view=net-9.0#system-runtime-interopservices-structlayoutattribute-charset>`__ layout attributes.
This allows a reference to a C# structure instance to be interpreted as a pointer to its C equivalent.

.. code-block:: cs

   [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
   public unsafe struct A3DRWParamsExportXMLData
   {
       // ...
   }

Note that the bindings structures directly requires an `unsafe context <https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/unsafe-code#232-unsafe-contexts>`__.

.. _cs_bindings_api:

Call Bindings
=============

Like structures, all functions from the C API are available in C# via the ``Direct.API`` namespace.


The following example shows how to call the ``A3DAsmModelFileExportToXMLFile`` function:

.. tabs::

   .. tab:: C#

      .. code-block:: cs

         public static A3DStatus ExportToXml(IntPtr modelFile, string outputFile)
         {
             A3DRWParamsExportXMLData export_params;
             API.Initialize(out export_params);
         
             export_params.m_bExportMetadata                   = true;
             export_params.m_bExportTransformations            = true;
             export_params.m_bExportColorMaterial              = true;
             export_params.m_bExportProductInformationByFormat = false;
         
             uint   mapSize    = 0;
             IntPtr mapXmlIds  = IntPtr.Zero;
             IntPtr mapPo      = IntPtr.Zero;
         
             return API.A3DAsmModelFileExportToXMLFile(
                 modelFile,
                 ref export_params,
                 outputFile,
                 out mapSize,
                 out mapXmlIds,
                 out mapPo
             );
         }
         
   .. tab:: C

      .. code-block:: c

         A3DStatus export_to_xml(A3DAsmModelFile* model_file, A3DUTF8Char* output_file)
         {
             A3DRWParamsExportXMLData export_params;
             A3D_INITALIZE_DATA(A3DRWParamsExportXMLData, export_params);
         
             export_params.m_bExportMetadata                   = A3D_TRUE;
             export_params.m_bExportTransformations            = A3D_TRUE;
             export_params.m_bExportColorMaterial              = A3D_TRUE;
             export_params.m_bExportProductInformationByFormat = A3D_FALSE;
         
             A3DUns32 map_size        = 0;
             unsigned int map_xml_ids = 0;
             A3DEntity** map_po       = 0;
         
             return API.A3DAsmModelFileExportToXMLFile(
                 model_file,
                 &export_params,
                 output_file,
                 &map_size,
                 &map_xml_ids,
                 &map_po
             );
         }

* Parameter types are translated to C# types (see :ref:`cs_bindings_types`).
* The C# ``string`` type can be passed directly as a function parameter, as it is marshaled using `UnmanagedType.LPUTF8Str <https://learn.microsoft.com/en-us/dotnet/framework/interop/default-marshalling-for-strings>`__.
* All entities handle types, such as ``A3DAsmModelFile*``, are passed as ``IntPtr``.
* Data types, such as ``A3DRWParamsExportXMLData`` are passed using ``ref``.
  This allows the C binaries to interpret them as C structure pointers.
* Write parameters are passed to the functions using ``out`` keyword.

All C# functions are declared as `function delegates <https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/delegates/>`__ that are assigned upon :doc:`loading the library <loader>`.
These delegate functions are located in the all-static ``API`` class under the ``Direct`` namespace:

.. code-block:: cs

   public class API
   {
       // ...

       public delegate A3DStatus PFA3DAsmModelFileExportToXMLFile(
           IntPtr                                    pA3DAsmModelFile,
           ref A3DRWParamsExportXMLData              pParamsExportData,
           [MarshalAs(UnmanagedType.LPUTF8Str)]
           string                                    pcXMLFileName,
           out uint                                  uMapSize,
           out IntPtr                                puMapXmlIds,
           out IntPtr                                ppMapProductOccurrences
       );

       public static PFA3DAsmModelFileExportToXMLFile A3DAsmModelFileExportToXMLFile = null;
   }


.. _cs_bindings_constants:

Constant Values
===============

Constant values exposed by the HOOPS Exchange C API are available in C# through the ``Direct.Constant`` static class.
This includes constants passed as structure fields, function parameters or returns from function calls:

.. tabs::

   .. tab:: C#

      .. code-block:: cs

         A3DHLRCurveData curve_data;
         API.Initialize(out curve_data);
         
         curve_data.m_cType = Constants.A3D_HLR_TYPE_SECTION;
         
   .. tab:: C

      .. code-block:: c

         A3DHLRCurveData curve_data = A3D_MAKE_DATA(A3DHLRCurveData);
         
         curve_data.m_cType = A3D_HLR_TYPE_SECTION;

.. _cs_bindings_enums:

Enumerators
===========

All enumerator types are available under the `Direct` namespace and can be used the same way as in the C API:

.. tabs::

   .. tab:: C#

      .. code-block:: cs

         A3DRWParamsExportJTData export_data = A3D_MAKE_DATA(A3DRWParamsExportJTData);
         
         export_data.m_eJTVersion         = kA3D_JT95;
         export_data.m_eWriteGeomTessMode = kA3DWriteGeomAndTess;
         
   .. tab:: C

      .. code-block:: c

         A3DRWParamsExportJTData export_data;
         API.Initialize(out export_data);
         
         export_data.m_eJTVersion         = A3DEJTVersion.kA3D_JT95;
         export_data.m_eWriteGeomTessMode = A3DEWriteGeomTessMode.kA3DWriteGeomAndTess;

.. _cs_bindings_types:

Integral Numeric Types
======================

:ref:`HOOPS Exchange C API typedefs <api_typedefs>` map to standard `integral numeric types <https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/integral-numeric-types>`__ in C#.

The table below provides the mapping between these types:

.. sidebar:: Entity Types

   All opaque pointer types to entities, such as ``A3DAsmModelFile*`` use the ``IntPtr`` C# type.

+----------------+------------+------------------------------------------+
| HE C Types     | C#         | Notes                                    |
+================+============+==========================================+
| ``A3DBool``    | ``bool``   | Can be either ``true`` or ``false``      |
+----------------+------------+------------------------------------------+
| ``A3DPtr``     | ``IntPtr`` | Integer large enough to hold a pointer   |
+----------------+------------+------------------------------------------+
| ``A3DVoid``    | ``void``   |                                          |
+----------------+------------+------------------------------------------+
| ``A3DInt8``    |            |                                          |
+----------------+ ``byte``   | Unsigned 8-bit integer                   |
| ``A3DUns8``    |            |                                          |
+----------------+------------+------------------------------------------+
| ``A3DInt16``   | ``short``  | Signed 16-bit integer                    |
+----------------+------------+------------------------------------------+
| ``A3DUint16``  | ``ushort`` | Unsigned 16-bit integer                  |
+----------------+------------+------------------------------------------+
| ``A3DInt32``   | ``int``    | Signed 32-bit integer                    |
+----------------+------------+------------------------------------------+
| ``A3DUns32``   | ``uint``   | Unsigned 32-bit integer                  |
+----------------+------------+------------------------------------------+

For more information about manipulating C-style arrays using the C# bindings API, see :doc:`utils`.
 
Conclusion
==========

This section introduced the core C# Bindings layer of the HOOPS Exchange API, providing a direct mapping to the C API.  
With access to functions, structures, enumerations, and constants, this layer forms the foundation for CAD data manipulation in C#.  

By understanding how to use this layer—such as structure initialization, function invocation, and type mappings—you can confidently work with the low-level elements of HOOPS Exchange.  
This knowledge is essential for building robust CAD applications and serves as a stepping stone to exploring higher-level abstractions provided in subsequent sections, like the :doc:`Library Loader <cs/loader>` and :doc:`Wrapper Classes <cs/classes>`.  
