Deprecated: Array and string offset access syntax with curly braces is deprecated in /homepages/21/d38531796/htdocs/jose/smfforum/Sources/Subs.php on line 3825
Dynamic API calls

IT-Consultant: Frederick J. Harris > Fred's API (Application Programming Interface) Tutorials

Dynamic API calls

(1/1)

Gérôme Guillemin:
Hello,

For those that are interested in Dynamic API call, I wrote years ago a simple API Call layer that was used into AutoHotkey scripting language and co.
Here's the C code MSVC++ and LCC WIn32 compatible (may be adapted for GCC) :


--- Code: ---//--------------------------------------------------------------------------------
//Author : Gerome GUILLEMIN
//Dynamic API :: the ultimate code !   
//--------------------------------------------------------------------------------
//!!!!!!!!!!!! POWER !!!!!!!!!!!!
//If you appreciate this sample code, please register to FBSL 
//Enjoy and take care 
//--------------------------------------------------------------------------------

//  Examples :

/*
   CallDllFx("Sleep","kernel32",1, 1000);
   CallDllFx("SleepEx","kernel32",2, 2000, 1);
   CallDllFx("WritePrivateProfileString","kernel32", 4, "Section1", "SecondKey", "By golly, it works.", "c:\\appname.ini");
*/

// C implementation:

int WINAPI CallDllFx (char *FuncName, char *DllName, int nArgs, ...)
{
HINSTANCE  hInst = 0;
FARPROC lpAddr    = 0;
int arg    = 0;
int result = 0;
char buff[128] = {'\0'};
va_list ap;
int argtable[128]; //[nArgs]; // in LCC WIN32 because of the Dynamic Support !
   
   memset( &argtable, 0, sizeof(argtable) );

   hInst=GetModuleHandle(DllName);
   if(hInst==NULL) {
      hInst=LoadLibrary(DllName);
   }
   else {
      //DBS( "(0)Library '%s' already loaded !", DllName );
   }
   lpAddr=(FARPROC)GetProcAddress(hInst,FuncName);
   if(lpAddr==NULL) {
      sprintf(buff,"%s%s",FuncName,"A");
      lpAddr=(FARPROC)GetProcAddress(hInst,buff);
   }
   if(lpAddr==NULL) {
      sprintf(buff,"%s%s","_",FuncName);
      lpAddr=(FARPROC)GetProcAddress(hInst,buff);
   }
   if (lpAddr) {
      va_start(ap,nArgs);
      for (register int i=0; i<nArgs;i++) {
         arg = va_arg(ap,int);
         argtable[i] = arg;
      }
      for (register int ii=nArgs-1;ii >=0; ii--) {
         arg = argtable[ii];
      }
      va_end( ap );
      __try {
         result = lpAddr();
      } __except ( EXCEPTION_EXECUTE_HANDLER ) {
         if (hInst) FreeLibrary(hInst);
         return -1;
      }

   }

   if(hInst) FreeLibrary(hInst);

return result;
}

--- End code ---

Enjoy !

Theo Gottwald:
Looks interesting, does somebody have this as PB-Code?

Patrice Terrier:
Theo,

This is the same technic being used in WinDev (PC-Soft) to call a DLL from their WL p-code.

It is not that hard to translate to PB ;)

Here is a small example, i wrote many years ago to encapsulate the first version of BASS.DLL


--- Code: ---    hBassDll??? = LoadLibrary("BASS.DLL")
    IF hBassDll??? THEN
       hBassWmaDll??? = LoadLibrary("BASSWMA.DLL")
       pBassPtr = GetProcAddress(hBassDll???, "BASS_GetVersion")
       IF pBassPtr THEN
          CALL DWORD pBassPtr USING BASS_GetVersion TO Ret???
          Version$ = TRIM$(STR$(LOWRD(Ret???))) + "." + TRIM$(STR$(HIWRD(Ret???)))
       END IF
       BassVer& = VAL(Version$) * 10
       IF BassVer& >= 18 THEN ' Basscd.dll requires at leats BASDLL version 1.8
          hBassEncodeDll??? = LoadLibrary("BASSENC.DLL")
          hBassCdDll??? = LoadLibrary("BASSCD.DLL")
          IF BassVer& >= 20 THEN ' Basscd.dll requires at leats BASDLL version 1.8
             hBassVisDll??? = LoadLibrary("BASS_VIS.DLL")
          END IF
       END IF
    END IF

--- End code ---
 

Added:
For the optional parameters, there is an ASM source code somewhere in POFF showing how to pass multiple parameters, that was done to work arround the PB6 or PB7 limitation of passing more than 16 parameters.

And for the current version, see the use of the "optional" keyword.

--- Quote ---Using classic optional parameters

When declaring a CDECL SUB or FUNCTION, you can specify trailing parameters as optional, using a set of brackets [..]:

DECLARE SUB KerPlunk CDECL (x%, y% [, z%])

Note that the comma separating the y% parameter from the optional z% parameter is inside the brackets.  The following calling sequences would then be valid:

CALL KerPlunk (x%, y%)

CALL KerPlunk (x%, y%, z%)

Optional parameters must be the last parameters designated in the list.

--- End quote ---

Eros Olmi:

--- Quote from: Theo Gottwald on March 04, 2009, 08:49:40 AM ---Looks interesting, does somebody have this as PB-Code?

--- End quote ---

Written some ages ago ...
http://www.powerbasic.com/support/pbforums/showthread.php?t=24175&highlight=calldll

Navigation

[0] Message Index

Go to full version