Command DLLFUNCTION Foundation

Creates a user-level function which executes a function of an external DLL. The command is deprecated. Use the EXTERN command instead.

Syntax
DLLFUNCTION <FunctionName>( [[@]<Parameters,...>] ) ;
      USING CDECL | OSAPI | STDCALL | SYSTEM ;
       FROM <DllName> 
Parameters
<FunctionName>
<FunctionName> designates the name of the funtion which must be contained in the DLL file <DllName>. It is executed by an Xbase++ function having the same name.
<Parameters,...>
<Parameters,...> is a comma separated list which contains the names of the formal function parameters of the DLL function <FunctionName>. If a parameter is to be passed by reference to the DLL function, it must be declared with a preceeding reference operator (@).
<CallingConv>
The option USING specifies the calling convention to be used for a DLL file. The following key words can be used for this option:
Options for the calling convention of DLL functions
Key word Description
CDECL C calling convention
OSAPI *) Calling convention for the operating system API
STDCALL Calling convention for the Windows 32bit API
SYSTEM Calling convention for the OS/2 API
  1. Can be used for OS/2 and Windows
<DllName>
<DllName> is the name of the DLL file that contains the function <FunctionName>. The file name can be specified as literal or as character expressions in parentheses.
Description

The DLLFUNCTION command is used to call functions from 32bit DLL files which are linked dynamically. It allows the utilization of functions within an Xbase++ application which are not known by the linker at the time when the EXE file is created. This includes operating system APIs as well as functions contained in DLLs of 3rd party producers.

The command creates an Xbase++ wrapper function which has the same name as the function contained in the DLL file <DllName>. Therefore, a DLL function can be called on the Xbase++ language level using a symbolic identifier.

When the Xbase++ function is called in a program, it first loads the DLL and then executes the DLL function of the same name. If parameters are declared, the Xbase++ function passes the received arguments to the DLL function. All parameters that are declared with a preceeding reference operator (@) are passed by reference to the DLL function. When the DLL function finishes, the DLL is unloaded and the Xbase++ function returns the return value of the DLL function.

The functional equivalent of DLLFUNCTION is provided by the functions DllLoad(), DllCall() and DllUnload().

When you use DLLs that are not created by Xbase++ you require a detailed knowledge about the interface of the called DLL function and the calling convention. Further information is found at function DllCall().

Examples
Declaration of system API functions

// The example uses Windows API functions to read the network name of 
// a work station from Windows' Registry database. Reading an entry 
// from the Registry is done with the user defined function 
// QueryRegistry() 

#include "Dll.ch" 

// #defines for the Registry database must comply 
// with the Windows SDK 

#define HKEY_CLASSES_ROOT           2147483648 
#define HKEY_CURRENT_USER           2147483649 
#define HKEY_LOCAL_MACHINE          2147483650 
#define HKEY_USERS                  2147483651 

#define KEY_QUERY_VALUE              1 
#define KEY_SET_VALUE                2 
#define KEY_CREATE_SUB_KEY           4 
#define KEY_ENUMERATE_SUB_KEYS       8 
#define KEY_NOTIFY                  16 
#define KEY_CREATE_LINK             32 


PROCEDURE Main 

   ? "NETNAME - determines the network name of a work station" 
   ? NetName() 

RETURN 

// Returns network name of a work station 
FUNCTION NetName() 
#ifdef __WIN32__ 
   LOCAL cKey, cEntry 

   cKey   := "System\CurrentControlSet\" + ; 
             "Control\ComputerName\ComputerName" 

   cEntry := "ComputerName" 

RETURN QueryRegistry( HKEY_LOCAL_MACHINE, cKey, cEntry ) 
#endif 
#ifdef __OS2__ 
RETURN GetEnv( "HOSTNAME" ) 
#endif 


// Declare Xbase++ wrapper functions for each API-call 

DLLFUNCTION RegOpenKeyExA( nHkeyClass, cKeyName, ; 
                           nReserved , nAccess , @nKeyHandle) ; 
      USING STDCALL ; 
       FROM ADVAPI32.DLL 

DLLFUNCTION RegQueryValueExA( nKeyHandle, cEntry   , nReserved, ; 
                              @nType    , @cName   , @nSize   ) ; 
      USING STDCALL ; 
       FROM ADVAPI32.DLL 

DLLFUNCTION RegCloseKey( nKeyHandle ) ; 
      USING STDCALL ; 
       FROM ADVAPI32.DLL 


// Read values from the Windows Registry database 

FUNCTION QueryRegistry( nHKEY, cKey, cEntry ) 
   LOCAL cName  := ""            // All parameters passed to 
   LOCAL nSize  := 0             // API functions must have 
   LOCAL nHandle:= 0             // a value not equal to NIL 
   LOCAL nType  := 0 
   LOCAL nRet 
                                 // Open Registry key 
   nRet := RegOpenKeyExA( nHKEY, cKey, ; 
                          0, KEY_QUERY_VALUE, @nHandle ) 

   IF nRet <> 0                  // Error 
      RETURN cName               // ** RETURN ** 
   ENDIF 
                                 // Determine size and type 
                                 // of the entry 
   RegQueryValueExA( nHandle, cEntry, 0, ; 
                     @nType , @cName, @nSize  ) 

   IF nSize > 0                  // Prepare empty string. It is 
      cName := Space( nSize-1 )  // passed by reference to the 
                                 // API and contains the result 
                                 // afterwards 
      RegQueryValueExA( nHandle, cEntry, 0, ; 
                        nType  , @cName, @nSize ) 

   ENDIF 

   RegCloseKey( nHandle )        // Close Registry key 
RETURN cName 

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.