# The main file

- Accessing the Gambas Programming Interface
- Declaring component classes
- Initializing and exiting of a component
- Interpreter hooks
- C++ specific notes
- The big picture

The component main file is a source file that :

- implements the component init and exit functions.
- declares the list of classes implemented in the component.
- may implement interpreter hooks.

The name of this file is usually `main.c` (or `main.cpp` if your component is written in C++), and the name of its header file is `main.h`.

## Accessing the Gambas Programming Interface

To access the Gambas Programming Interface, you need :

- To include `gambas.h` in each component source file.
- To declare an exported global structure named `GB` that will receive the interface.
- To have a reference to the `GB` symbol.

The global structure must be declared this way :

      GB_INTERFACE GB;

The source file must reference this structure this way :

      extern GB_INTERFACE GB;

As every source file must reference the `GB` interface and include the `gambas.h` file, the easiest way is to put them in the `main.h` file, to declare `GB` in `main.c`, and to include `main.h` everywhere.

So `main.h` will look like this :

      /* main.h */

      #ifndef __MAIN_H
      #define __MAIN_H

      #include "gambas.h"

      #ifndef __MAIN_C
      extern GB_INTERFACE GB;
      #endif

      ...

      #endif

And `main.c` will look like this :

      /* main.c */

      #define __MAIN_C

      #include "main.h"

      ...

      GB_INTERFACE GB;

      ...

## Declaring component classes

Each class you implement in your component has its own description structure declared in its own source file. This structure is declared in the header file of the class source file.

So, you must include every class header file in `main.c` :

      /* main.c */

      #define __MAIN_C

      #include "main.h"

      #include "FirstClassSourceFile.h"
      #include "SecondClassSourceFile.h"
      ...

      GB_INTERFACE GB;

      ...

Then, you must declare a global null-terminated array that will contain a pointer to each class structure declared in the included header files. The name of this array must be `GB_CLASSES`.

Note : a class source file can declare and implement more than one class.

See Writing a class for more information about class source files.

      /* main.c */

      ...

      GB_INTERFACE GB;

      GB_DESC *GB_CLASSES[] =
      {
        FirstClassDescription,
        SecondClassDescription,
        ThirdClassDescription,
        ...,
        NULL
      };

## Initializing and exiting of a component

The component must export two global functions : the first is called when the interpreter loads the component, and the second is called when the interpreter unloads it.

The name of the function called at loading must be `GB_INIT`.

      /* main.c */

      ...

      int GB_INIT(void)
      {
        ...
      }

This function receives no argument, and must return a non-zero integer value to tell the interpreter that he must keep the component shared libraries in memory after unloading.

Note : Some shared libraries, like the X-Window library, can crash a process if they are unloaded before its end. As the QT library uses the X-Window library, the QT component must be kept in memory at unloading.

The main job of `GB_INIT()` is to declare interpreter hooks.

As for the function called at component unloading, its name must be `GB_EXIT`.

      /* main.c */

      ...

      void GB_EXIT(void)
      {
      }

      ...

This function takes no argument and returns nothing. It usually does nothing, but you can use it to provide specific uninitializations.

## Interpreter hooks

Interpreter hooks must be declared during the `GB_INIT()` function execution. Consequently, hooks functions are usually implemented in the `main.c` file.

For example, here is the QT component `GB_INIT()` function :

      /* main.cpp of QT component */

      int GB_INIT(void)
      {
        GB.Hook(GB_HOOK_MAIN, (void *)my_main);
        GB.Hook(GB_HOOK_LOOP, (void *)my_loop);
        GB.Hook(GB_HOOK_WAIT, (void *)my_wait);
        GB.Hook(GB_HOOK_WATCH, (void *)my_watch);
        GB.Hook(GB_HOOK_POST, (void *)my_post);

        return 1;
      }

To get more information about hooks, go to The interpreter hooks

## C++ specific notes

In short, a component must export four symbols to the interpreter : `GB`, `GB_CLASSES`, `GB_INIT` and `GB_EXIT`.

If you program a component in C++, you must enclose the declaration of these symbols between `extern "C" {` and `}` so that the C++ linker does not transform their names.

Here is an extract of the `main.cpp` file of the QT component :

      extern "C" {

      GB_DESC *GB_CLASSES[] =
      {
        ...
      };

      ...

      int GB_INIT(void)
      {
        GB.Hook(GB_HOOK_MAIN, (void *)my_main);
        GB.Hook(GB_HOOK_LOOP, (void *)my_loop);
        GB.Hook(GB_HOOK_WAIT, (void *)my_wait);
        GB.Hook(GB_HOOK_WATCH, (void *)my_watch);
        GB.Hook(GB_HOOK_POST, (void *)my_post);

        return 1;
      }

      void GB_EXIT()
      {
        ...
      }

      } /* extern "C" */

## The big picture

      /* example of main.c */

      #define __MAIN_C

      #include "main.h"

      #include "FirstClassSourceFile.h"
      #include "SecondClassSourceFile.h"
      #include "ThirdClassSourceFile.h"

      GB_INTERFACE GB;

      GB_DESC *GB_CLASSES[] =
      {
        FirstClassDescription,
        SecondClassDescription,
        ThirdClassDescription
        NULL
      };

      static void my_error(int code, char *error, char *where)
      {
        ...
      }

      int GB_INIT(void)
      {
        GB.Hook(GB_HOOK_ERROR, (void *)my_error);

        return 0;
      }