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) :
//--------------------------------------------------------------------------------
//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;
}
Enjoy !
Looks interesting, does somebody have this as PB-Code?
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
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
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.
Quote from: Theo Gottwald on March 04, 2009, 08:49:40 AM
Looks interesting, does somebody have this as PB-Code?
Written some ages ago ...
http://www.powerbasic.com/support/pbforums/showthread.php?t=24175&highlight=calldll