Function _conRegisterDll() Foundation

Registers DLL written in C at load time

Syntax
BOOL XPPAPIENTRY _conRegisterDll(ULONG dllHandle, 
                                 XppDllRegistration *pDllRecord);
Parameters
dllHandle
The handle of the DLL to register. If the handle is not of type ULONG, a type cast is necessary when passing the value.
*pDllRecord
The pointer to a static record of the XppDllRegistration type. A value of NULL is not allowed.
Return

The function returns TRUE if the registration was accepted, FALSE if not enough memory was available to complete the operation.

Description

A DLL created by a C-development kit can be linked to an Xbase++ - executable, or can be loaded and unloaded dynamically by using DllLoad() and DllUnload(), respectively. Using _conRegisterF() for symbol initialization, will make this DLL behave almost as any Xbase++ - DLL. For this to work, _conRegisterDll() must be used in the DLL's DllMain() function to register it with the Xbase kernel.

Although non-Xbase++ DLLs can be loaded dynamically, there is a difference in the DLL initialization compared to Xbase++ DLLs that must be recognized: An Xbase++ - DLL and other DLLs statically linked to it are first loaded and low-level initialized. Then, the Xbase++ - initialization is performed for each DLL. Finally, all INIT-procedures are called. This ensures the runtime to be fully operational at the time the first INIT-procedure is called.

In contrast, a plain C-DLL will be initialized "DLL-by-DLL", that is, each DLL is fully initialized before proceeding to the next one. This can lead to errors when using functionality from other DLLs in initialization code because these may not yet be initialized.

The order in which all initialization (low-level, Xbase++ - level, INIT-procedure-level) is performed, however, depends on the OS loader and must be assumed to be random in all cases.

The function can be used for statically linked DLLs or when dynamic loading is desired.

Examples
// ------------------------------------------------ 
// C-API code for dynamic registration of a DLL 

#include "windows.h" 
#include "xppdef.h" 
#include "xppcon.h" 

// This is a function usable by Xbase++. 
XPPRET XPPENTRY C_TESTFUNC(XppParamList paramList); 

XPPRET XPPENTRY C_TESTFUNC(XppParamList paramList) { 

  ContainerHandle chResult = _conNew(NULLCONTAINER); 
  
  _conPutCL( chResult, "TESTFUNC", 8 );      
  _conReturn( paramList, chResult); 
  _conRelease( chResult); 

} 

/* 
* This is the description of the symbol registration 
* information, see _conRegisterF(). 
*/ 
XppRegisterFunction MyFuncs[1] = { { "_C_TESTFUNC", C_TESTFUNC } }; 
XppRegisterTable MyFuncsInfo; 

/* 
* This is the DLL registration record. It incorporates the 
* descriptions for the symbol registration, and pointers to 
* C-implemented INIT/EXIT procedures. 
*/ 
XppDllRegistration MyDllRecord = {MyFuncs, 
                                 sizeof(MyFuncs) / sizeof(XppRegisterFunction), 
                                 0, cdllinit, cdllexit, "Hi"}; 

/* 
* This is the user-defined INIT procedure for this DLL. 
* If this function is called, the Xbase++ runtime (and possible 
* C-Runtime-Dlls) are operational. 
*/ 
ULONG XPPAPIENTRY cdllinit(void *data) 
{ 
  char *name = (char*)data; 
  /* in this case, data can be casted to (char*) 
   * and points to the "Hi"-string of the 
   * DLL registration record. 
   */ 
  return 1; 
} 

/* 
* This is the user-defined EXIT procedure for this DLL. 
* If this function is called, the Xbase++ runtime (and possible 
* C-Runtime-Dlls) is still operational. 
*/ 
ULONG XPPAPIENTRY cdllexit(void *data) 
{ 
  char *name = (char*)data; 
  /* in this case, data can be casted to (char*) 
   * and points to the "Hi"-string of the 
   * DLL registration record. 
   */ 
  return 1; 
} 

/* 
* This is the Dll-init function which will be called 
* by the OS loader. The function symbol must be linked 
* as the DLL entry point. 
*/ 

#ifdef __IBMCPP__ 
unsigned long __stdcall _DLL_InitTerm(unsigned long hModule, unsigned long 
                                           ulFlag, LPVOID dummy) 
#else 
BOOL WINAPI DllMain(HINSTANCE hModule, DWORD ulFlag, LPVOID dummy) 
#endif 
{ 
  switch (ulFlag) { 

     case DLL_PROCESS_ATTACH : 
        /* Register the DLL to the Xbase++ Runtime 
         * This is the only valid call to the C-API at this point. 
         */ 
        if (!_conRegisterDll((ULONG)hModule, &MyDllRecord)) 
           return 0; 
        break; 

     case DLL_PROCESS_DETACH : 
        /* Deregister the DLL.  
         * This is the only valid call to the C-API at this point. 
         */ 
        _conUnRegisterDll((ULONG)hModule); 
        break; 

     default: 
        return 0; 
  } 

  return 1; 
} 

Feedback

If you see anything in the documentation that is not correct, does not match your experience with the particular feature or requires further clarification, please use this form to report a documentation issue.