diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 9c319c73e6..f2e901fc78 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,40 @@ past entries belonging to author(s): Viktor Szakats. */ +2010-02-15 10:05 UTC+0100 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/include/hbvm.h + * harbour/src/vm/hvm.c + + added new C function hb_vmFindFuncSym() which looks for function with + given name registered in HVM by dynamically loaded library. It looks + for public function and if public function cannot be located it tries + to find first static function which has requested name. + + * harbour/include/hbapi.h + * harbour/src/vm/dynlibhb.c + + added new C functions to manage dynamic libraries: + PHB_ITEM hb_libLoad( PHB_ITEM pLibName, PHB_ITEM pArgs ); + HB_BOOL hb_libFree( PHB_ITEM pDynLib ); + void * hb_libHandle( PHB_ITEM pDynLib ); + void * hb_libSymAddr( PHB_ITEM pDynLib, const char * pszSymbol ); + + * harbour/include/hbextern.ch + * harbour/src/vm/dynlibhb.c + - removed HB_LIBDO() PRG function. If someone used it then please + use DO() instead + + added new PRG function: + HB_LIBGETFUNSYM( , ) -> | NIL + It works in similar way to HB_HRBGETFUNSYM() but it looks for + PRG function in given library. It tries to find public function + and if such function does not exists it looks for first static one. + is library handle returned by HB_LIBLOAD() + is PRG function name. + is symbol of located function + If function can be found HB_LIBGETFUNSYM() returns NIL. + Warning: this function returns only symbols for functions registered + in HVM when library was loaded. It will not return symbols + for functions written in C and not explicitly registered + using own symbol table. + 2010-02-14 17:34 UTC-0800 Pritpal Bedi (pritpal@vouchcac.com) * contrib/gtwvg/wvgscrlb.prg ! Defined method :configure() as VIRTUAL. diff --git a/harbour/include/hbapi.h b/harbour/include/hbapi.h index c4b8d05455..c075f5dbc8 100644 --- a/harbour/include/hbapi.h +++ b/harbour/include/hbapi.h @@ -1106,6 +1106,10 @@ extern HB_EXPORT void hb_vmSetDefaultGT( const char * szGtName ); extern HB_EXPORT PHB_FUNC hb_vmProcAddress( const char * szFuncName ); +extern HB_EXPORT PHB_ITEM hb_libLoad( PHB_ITEM pLibName, PHB_ITEM pArgs ); +extern HB_EXPORT HB_BOOL hb_libFree( PHB_ITEM pDynLib ); +extern HB_EXPORT void * hb_libHandle( PHB_ITEM pDynLib ); +extern HB_EXPORT void * hb_libSymAddr( PHB_ITEM pDynLib, const char * pszSymbol ); /* misc */ extern HB_EXPORT const char * hb_verCPU( void ); /* retrieves a constant string with CPU architecture */ diff --git a/harbour/include/hbextern.ch b/harbour/include/hbextern.ch index 4a03a26ae5..f2a8360796 100644 --- a/harbour/include/hbextern.ch +++ b/harbour/include/hbextern.ch @@ -958,7 +958,7 @@ EXTERNAL HB_HRBGETFUNSYM EXTERNAL HB_LIBLOAD EXTERNAL HB_LIBFREE -EXTERNAL HB_LIBDO +EXTERNAL HB_LIBGETFUNSYM EXTERNAL HB_LIBERROR EXTERNAL HB_RANDOM diff --git a/harbour/include/hbvm.h b/harbour/include/hbvm.h index b219a619bc..da9fd8d4bc 100644 --- a/harbour/include/hbvm.h +++ b/harbour/include/hbvm.h @@ -101,6 +101,7 @@ extern HB_EXPORT PHB_SYMB hb_vmProcessDynLibSymbols( PHB_SYMB pSymbols, HB_USHOR extern void hb_vmBeginSymbolGroup( void * hDynLib, HB_BOOL fClone ); extern void hb_vmInitSymbolGroup( void * hNewDynLib, int argc, const char * argv[] ); extern void hb_vmExitSymbolGroup( void * hDynLib ); + extern PHB_SYMB hb_vmFindFuncSym( const char * szFuncName, void * hDynLib ); extern const char * hb_vmFindModuleSymbolName( PHB_SYMB pSym ); extern HB_BOOL hb_vmFindModuleSymbols( PHB_SYMB pSym, PHB_SYMB * pSymbols, HB_USHORT * puiSymbols ); extern PHB_SYMB hb_vmGetRealFuncSym( PHB_SYMB pSym ); diff --git a/harbour/src/vm/dynlibhb.c b/harbour/src/vm/dynlibhb.c index 24aa222b1e..07691148a9 100644 --- a/harbour/src/vm/dynlibhb.c +++ b/harbour/src/vm/dynlibhb.c @@ -93,20 +93,20 @@ static const HB_GC_FUNCS s_gcDynlibFuncs = hb_gcDummyMark }; -HB_FUNC( HB_LIBLOAD ) +PHB_ITEM hb_libLoad( PHB_ITEM pLibName, PHB_ITEM pArgs ) { void * hDynLib = NULL; - if( hb_parclen( 1 ) > 0 ) + if( hb_itemGetCLen( pLibName ) > 0 ) { - int argc = hb_pcount() - 1, i; + int argc = pArgs ? ( int ) hb_arrayLen( pArgs ) : 0, i; const char ** argv = NULL; if( argc > 0 ) { argv = ( const char** ) hb_xgrab( sizeof( char* ) * argc ); for( i = 0; i < argc; ++i ) - argv[i] = hb_parcx( i + 2 ); + argv[ i ] = hb_arrayGetCPtr( pArgs, i + 1 ); } if( hb_vmLockModuleSymbols() ) @@ -117,7 +117,7 @@ HB_FUNC( HB_LIBLOAD ) { void * hFileName; - hDynLib = ( void * ) LoadLibrary( HB_PARSTR( 1, &hFileName, NULL ) ); + hDynLib = ( void * ) LoadLibrary( HB_ITEMGETSTR( pLibName, &hFileName, NULL ) ); hb_strfree( hFileName ); } @@ -126,11 +126,11 @@ HB_FUNC( HB_LIBLOAD ) HB_UCHAR LoadError[ 256 ] = ""; /* Area for load failure information */ HMODULE hDynModule; if( DosLoadModule( ( PSZ ) LoadError, sizeof( LoadError ), - ( PCSZ ) hb_parc( 1 ), &hDynModule ) == NO_ERROR ) + ( PCSZ ) hb_itemGetCPtr( pLibName ), &hDynModule ) == NO_ERROR ) hDynLib = ( void * ) hDynModule; } #elif defined( HB_HAS_DLFCN ) - hDynLib = ( void * ) dlopen( hb_parc( 1 ), RTLD_LAZY | RTLD_GLOBAL ); + hDynLib = ( void * ) dlopen( hb_itemGetCPtr( pLibName ), RTLD_LAZY | RTLD_GLOBAL ); #else { int iTODO; @@ -150,16 +150,16 @@ HB_FUNC( HB_LIBLOAD ) { void ** pLibPtr = ( void ** ) hb_gcAllocate( sizeof( void * ), &s_gcDynlibFuncs ); * pLibPtr = hDynLib; - hb_retptrGC( pLibPtr ); + return hb_itemPutPtrGC( NULL, pLibPtr ); } - else - hb_ret(); + + return NULL; } -HB_FUNC( HB_LIBFREE ) +HB_BOOL hb_libFree( PHB_ITEM pDynLib ) { HB_BOOL fResult = HB_FALSE; - void ** pDynLibPtr = ( void ** ) hb_parptrGC( &s_gcDynlibFuncs, 1 ); + void ** pDynLibPtr = ( void ** ) hb_itemGetPtrGC( pDynLib, &s_gcDynlibFuncs ); if( pDynLibPtr && *pDynLibPtr && hb_vmLockModuleSymbols() ) @@ -179,7 +179,57 @@ HB_FUNC( HB_LIBFREE ) } hb_vmUnlockModuleSymbols(); } - hb_retl( fResult ); + + return fResult; +} + +void * hb_libHandle( PHB_ITEM pDynLib ) +{ + void ** pDynLibPtr = ( void ** ) hb_itemGetPtrGC( pDynLib, &s_gcDynlibFuncs ); + + return pDynLibPtr ? *pDynLibPtr : NULL; +} + +void * hb_libSymAddr( PHB_ITEM pDynLib, const char * pszSymbol ) +{ + void * hDynLib = hb_libHandle( pDynLib ); + + if( hDynLib ) + { +#if defined( HB_OS_WIN ) + return ( void * ) GetProcAddress( ( HMODULE ) hDynLib, pszSymbol ); +#elif defined( HB_OS_OS2 ) + PFN pProcAddr = NULL; + if( DosQueryProcAddr( ( HMODULE ) hDynLib, 0, pszSymbol, &pProcAddr ) == NO_ERROR ) + return ( void * ) pProcAddr; +#elif defined( HB_HAS_DLFCN ) + return dlsym( hDynLib, pszSymbol ); +#endif + } + return NULL; +} + +HB_FUNC( HB_LIBLOAD ) +{ + int iPCount = hb_pcount(), i; + PHB_ITEM pArgs = NULL; + + if( iPCount > 1 ) + { + pArgs = hb_itemArrayNew( iPCount - 1 ); + for( i = 2; i <= iPCount; ++i ) + hb_arraySet( pArgs, i, hb_param( i, HB_IT_ANY ) ); + } + + hb_itemReturnRelease( hb_libLoad( hb_param( 1, HB_IT_ANY ), pArgs ) ); + + if( pArgs ) + hb_itemRelease( pArgs ); +} + +HB_FUNC( HB_LIBFREE ) +{ + hb_retl( hb_libFree( hb_param( 1, HB_IT_ANY ) ) ); } HB_FUNC( HB_LIBERROR ) @@ -191,29 +241,23 @@ HB_FUNC( HB_LIBERROR ) #endif } -/* Executes a Harbour pcode dynamically loaded DLL function or procedure - * Syntax: HB_libDo( [,] ) --> [] +/* Get FUNCTION or PROCEDURE symbol from given library. + * hb_libGetFunSym( , ) -> | NIL */ - -HB_FUNC( HB_LIBDO ) +HB_FUNC( HB_LIBGETFUNSYM ) { - if( hb_parclen( 1 ) > 0 ) + const char * szFuncName = hb_parc( 2 ); + + if( szFuncName ) { - PHB_DYNS pDynSym = hb_dynsymFindName( hb_parc( 1 ) ); + void * hDynLib = hb_libHandle( hb_param( 1, HB_IT_ANY ) ); - if( pDynSym ) + if( hDynLib ) { - int iPCount = hb_pcount(); - int iParam; + PHB_SYMB pSym = hb_vmFindFuncSym( szFuncName, hDynLib ); - hb_vmPushSymbol( pDynSym->pSymbol ); - hb_vmPushNil(); - - /* same logic here as from HB_FUNC( EVAL ) */ - for( iParam = 2; iParam <= iPCount; iParam++ ) - hb_vmPush( hb_stackItemFromBase( iParam ) ); - - hb_vmProc( ( HB_USHORT ) ( iPCount - 1 ) ); + if( pSym ) + hb_itemPutSymbol( hb_stackReturnItem(), pSym ); } } } diff --git a/harbour/src/vm/hvm.c b/harbour/src/vm/hvm.c index 45bde58e83..7b89539c8e 100644 --- a/harbour/src/vm/hvm.c +++ b/harbour/src/vm/hvm.c @@ -7326,6 +7326,41 @@ HB_BOOL hb_vmFindModuleSymbols( PHB_SYMB pSym, PHB_SYMB * pSymbols, return HB_FALSE; } +PHB_SYMB hb_vmFindFuncSym( const char * szFuncName, void * hDynLib ) +{ + static PHB_SYMB pFuncSym = NULL; + + if( szFuncName ) + { + PHB_SYMBOLS pSymbols = s_pSymbols; + + while( pSymbols ) + { + if( pSymbols->hDynLib == hDynLib ) + { + HB_USHORT ui; + + for( ui = 0; ui < pSymbols->uiModuleSymbols; ++ui ) + { + PHB_SYMB pSymbol = &pSymbols->pModuleSymbols[ ui ]; + + if( ( pSymbol->scope.value & HB_FS_LOCAL ) != 0 && + hb_stricmp( pSymbol->szName, szFuncName ) == 0 ) + { + if( ( pSymbol->scope.value & HB_FS_STATIC ) == 0 ) + return pSymbol; + else if( ! pFuncSym ) + pFuncSym = pSymbol; + } + } + } + pSymbols = pSymbols->pNext; + } + } + + return pFuncSym; +} + #define HB_SYM_STATICSBASE( p ) \ ( ( PHB_ITEM ) ( ( (p)->scope.value & HB_FS_FRAME ) ? \ (p)->value.pStaticsBase : NULL ) )