Unloading and InitializeInterface

These interfaces define functions that manage different hardware configurations when the application initializes and unloads.

InitializeInterface is an interface pointer that points to a (void *(*)(AOInterface_t *)) function. This function is called automatically to determine the actual value of any interface pointer whose initial value was NULL. This allows DLLs to create or choose certain interfaces at runtime instead of at compile time.

Unloading is an interface pointer that points to a (void (*)(void)) function. If you call AoRelease(), and the count reaches zero, the unloading function is called before the DLL is unloaded. This gives controls that access hardware a chance to leave that hardware in a stable state before being unloaded.

Let's say we have an addon that supports two slightly different pieces of hardware. In this case, we want two different HardwareControl interfaces, and we want to use the one that the hardware the user has installed is for. In this case, we set the interface pointer for the HardwareControl interface to NULL, and create a InitializeInterface interface that returns the appropriate interface. Also, we want to do some cleanup on the hardware when its done, so we implement a Unloading interface as well:

static void *InitializeInterface(AOInterface_t *i)
{
        // we only initialize the "HardwareControl" interface
        if (strcmp(i->name,"HardwareControl")!=0) return 0;

        // return the HardwareControlA/BInterface if either type of
        // hardware is found.
        if (hardware_is_type_a)
                return HardwareControlAInterface;
        else
        if (hardware_is_type_b)
                return HardwareControlBInterface;

        // neither piece of hardware found? return 0
        return 0;
}

static void Unloading(void)
{
        // release the hardware, whatever it is
        release_hardware();
}

AOInterface_t my_hardware_interface[] =
{
        {"Name",0,"my_hardware"},
        {"Description",0,"Plugin for my hardware"},
        {"HardwareControl",0,NULL},
        {"InitializeInterface",0,InitializeInterface},
        {"Unloading",0,Unloading},
        ... (other interfaces)
        {0,0,0},
};

The first time an application requests the HardwareControl interface for the above addon, the Addon Interfaces Library sees that the interface pointer is 0, and calls the InitializeInterface() function with the HardwareControl AOInterface_t as its parameter. The InitializeInterface() function recognizes the HardwareControl interface, checks which hardware is available, and returns the appropriate interface pointer.

Later, when the DLL is unloading, or the application is exiting, the Addon Interfaces Library checks to see if the addon has an Unloading interface, and because it does, that function in the addon is called.