Initializing the PFI
This page applies to Harlequin v13.1r0 and later; and to Harlequin MultiRIP but not Harlequin Core
The pfi.h
header includes a macro called DO_PFI_INIT(p)
, which is applied to the (void *)
argument of the D_LIB_SELECT
selector, returning TRUE
or FALSE
. It will return TRUE
only once in the time a given plugin is loaded.
In the plugin's handler for the D_LIB_SELECT
selector, it should first pass its (void *)
argument through to PluginLibSelect
as usual. Immediately afterwards, and only if PluginLibSelect
returns NOERR
, the handler should apply DO_PFI_INIT(p)
to the argument. If TRUE
, the plugin may proceed then (or at a later point) to initialize the PFI.
Here is an example of the use of the macro:
case D_LIB_SELECT:
nStatus = PluginLibSelect(ppluglibglobals,
(devLibSelectParam *)pParam); if ((nStatus == NOERR) && DO_PFI_INIT(pParam))
{
InitialisePFI();
}
break;
Plugins initialize the PFI by calling the PlgPFIInitialise
function:
/* Return values */ #define PFI_INIT_OK
#define PFI_INIT_ERR_SOME_FUNCTIONS_UNKNOWN
#define PFI_INIT_ERR_NO_GATEWAY
#define PFI_INIT_ERR_VERSION_INCOMPATIBLE #define PFI_INIT_ERR_CALLBACK_INVALID
#define PFI_INIT_ERR_ALREADY_INITIALISED
uint32 PlgPFIInitialise(
uint32 *pnFuncNumbers, uint32 cFuncNumbers, uint32 *pnMaj, *pnMin,
void (*pfCallBack)(uint32, uint32, PlgFwTextString)
);
passing it an array of the ordinal numbers of any PFI functions it may use, the number of elements in that array, and pointers to a value containing the major and minor plugin interface version number set in the D_GET_IDENTITY
selector that will already have occurred, (and which could be modified in the case of PFI_INIT_ERR_VERSION_INCOMPATIBLE
being set in the return value).
Plugins should set wMaj/wMin
to at least 14
/0
the earliest plugin‐interface version supported by the PFI.
The final argument is a mandatory pointer to a function within the plugin which will be called upon a major error. This is discussed in The callback function .
The function returns PFI_INIT_OK
or a bitmask of error values. PFI_INIT_OK
indicates that the call succeeded, and the plugin should not call the routine again. The possible error values used in the bitmask are as follows:
| The call failed because some functions are not supported by the RIP or plugin library. If no other errors preclude it, the call could be made again with a different (perhaps simpler) list. |
| The call failed because the |
| The call failed because the plugin interface version number supplied post‐dates the plugin library's own version. The values in |
| The callback function pointer was NULL. The plugin may call this routine again, but will continue to get this error unless a valid callback function pointer is supplied. |
| The PFI has already been initialized successfully. The plugin should not call this routine again. No damage has been done to the configuration. |
If PlgPFIInitialise
does not return PFI_INIT_OK
, the plugin may continue but must not use PFI routines. Once it has returned PFI_INIT_OK
, the plugin should not call PlgPFIInitialise
again in the loaded lifetime of the plugin.
If the plugin attempts to call any of the PFI functions before it has first successfully called PlgPFIInitialise
for that function, the plugin may cause unpredictable and possibly fatal problems to occur.
Here is example usage of PlgPFIInitialise()
. This example lists only ePlgFwError
functions to keep the list short. Real world usage would include more, and more diverse, function numbers.
static void InitialisePFI(void)
{
static uint32 awFuncNumbers[] =
{
ePlgFwErrorStateAlloc, ePlgFwErrorStateFree, ePlgFwErrorStateClear, ePlgFwErrorIsSuccess, ePlgFwErrorOrdinalFromState, ePlgFwErrorIsDescendant, ePlgFwErrorOrdinalIsKnown, ePlgFwErrorPrintf, ePlgFwErrorSet,
ePlgFwErrorPlatformErrorFromState,
};
uint32 wRetVal;
uint32 wMaj = 14;
uint32 wMin = 0;
wRetVal = PlgPFIInitialise(
&awFuncNumbers[0], sizeof(awFuncNumbers)/sizeof(*awFuncNumbers), &wMaj, &wMin,
&PFICallbackFunction);
}