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( <pLibHandle>, <cFuncName> ) -> <sFuncSym> | 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.
      <pLibHandle> is library handle returned by HB_LIBLOAD()
      <cFuncName> is PRG function name.
      <sFuncSym> 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.
This commit is contained in:
Przemyslaw Czerpak
2010-02-15 09:05:58 +00:00
parent 78ddb279db
commit b0f4f1f4a1
6 changed files with 149 additions and 31 deletions

View File

@@ -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( <pLibHandle>, <cFuncName> ) -> <sFuncSym> | 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.
<pLibHandle> is library handle returned by HB_LIBLOAD()
<cFuncName> is PRG function name.
<sFuncSym> 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.

View File

@@ -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 */

View File

@@ -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

View File

@@ -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 );

View File

@@ -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( <cFuncName> [,<params...>] ) --> [<uResult>]
/* Get FUNCTION or PROCEDURE symbol from given library.
* hb_libGetFunSym( <pLibHandle>, <cFuncName> ) -> <sFuncSym> | 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 );
}
}
}

View File

@@ -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 ) )