Ejemplo n.º 1
0
/**
 * @brief Open library
 * @param libName - [in] library file name
 * @return true - loaded successfully, false otherwise
 */
bool DynamicLibrary::Open( const PDL_CHAR * libName, bool resolveSymbols )
{
	if ( !libName ) { return false; }

	library_ =
#if PLATFORM_WIN32
		::LoadLibraryExA( libName, NULL,
		                  ( resolveSymbols ) ? 0 : DONT_RESOLVE_DLL_REFERENCES );
#elif PLATFORM_POSIX
		dlopen( libName, RTLD_GLOBAL | ( ( resolveSymbols ) ? RTLD_NOW : RTLD_LAZY ) );
#endif

	if ( library_ ) { libraryName_ = libName; }
	else
	{
		const pdl_string nameWithExt( pdl_string( libName ) + pdl_string( GetDefaultExt() ) );
		library_ =
#if PLATFORM_WIN32
			::LoadLibraryExA( nameWithExt.c_str(), NULL,
		                      ( resolveSymbols ) ? 0 : DONT_RESOLVE_DLL_REFERENCES );
#elif PLATFORM_POSIX
			dlopen( nameWithExt.c_str(), RTLD_GLOBAL | ( ( resolveSymbols ) ? RTLD_NOW : RTLD_LAZY ) );
#endif
		if ( library_ ) { libraryName_ = libName; }
	}

	return ( library_ );
}
Ejemplo n.º 2
0
/**
 * @brief Get dynamic library
 * @param libName - [in] library file name
 * @return dynamic library
 * @throw LoaderException - cannot load library
 */
DynamicLibrary & DynamicLibraryManager::GetLibrary( const PDL_CHAR * libName )
{
	DynamicLibrary & library = GetLibraryInstance( libName );

	if ( !library.Opened() )
	{
		// We tried to load this library before, but we've failed
		throw LoaderException( pdl_string( "Cannot load library `" ) +
		                       pdl_string( libName ) + pdl_string( "`" ) );
	}

	return library;
}
Ejemplo n.º 3
0
/**
 * @brief Get last error description
 * @return last error description
 */
pdl_string DynamicLibrary::GetLastError() const
{
	try
	{
#if PLATFORM_WIN32
		LPSTR lpMsgBuf = NULL;
		const DWORD res =
			::FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
			                  NULL, ::GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
	                          reinterpret_cast< LPSTR >( &lpMsgBuf ), 0, NULL );
		pdl_string errorText;
		if ( res != 0 )
		{
			errorText.assign( lpMsgBuf );
			( void ) ::LocalFree( lpMsgBuf );
		}
#elif PLATFORM_POSIX
		const pdl_string errorText( dlerror() );
#endif
		return errorText;
	}
	catch ( ... )
	{
		return pdl_string();
	}
}
Ejemplo n.º 4
0
/**
 * @brief Get symbol by name
 * @param symbolName - [in] symbol name
 * @return pointer to symbol, 0 if not found
 */
void * DynamicLibrary::GetSymbolByName( const PDL_CHAR * symbolName )
{
	if ( !library_ )
	{
		throw LoaderException( pdl_string( "Library is not opened" ) );
	}

	return
#if PLATFORM_WIN32
		static_cast< void * >( ::GetProcAddress( library_, symbolName ) );
#elif PLATFORM_POSIX
		dlsym( library_, symbolName );
#endif
}
Ejemplo n.º 5
0
/**
 * @brief Get class instance
 * @param className - [in] class name
 * @return pointer to class instance
 */
DynamicClass * DynamicLibrary::GetInstance( const PDL_CHAR * className )
{
	const InstanceMap::iterator loadedInstance( instances_.find( className ) );
	if ( loadedInstance != instances_.end() ) { return ( loadedInstance -> second ); }
	
	const pdl_string builderName( pdl_string( "Create" ) + pdl_string( className ) );
	
	// Tricky code to prevent compiler error
	// ISO C++ forbids casting between pointer-to-function and pointer-to-object
	DynamicBuilder builder = 0;
	void * symbol = GetSymbolByName( builderName.c_str() );
	( void ) memcpy( &builder, &symbol, sizeof( void * ) );
	
	if ( !builder )
	{
		instances_[ className ] = 0;
		throw LoaderException( pdl_string( "Class `" ) + pdl_string( className ) +
		                       pdl_string( "` not found in " )  + libraryName_ );
	}

	DynamicClass * instance = ( DynamicClass * )( *builder )();
	instances_[ className ] = instance;
	return instance;
}
Ejemplo n.º 6
0
/**
 * @brief Get dynamic library instance
 * @param libName - [in] library file name
 * @return dynamic library instance
 */
DynamicLibrary & DynamicLibraryManager::GetLibraryInstance( const PDL_CHAR * libName )
{
	if ( !libName )
	{
		throw LoaderException( pdl_string( "Library name is 0" ) );
	}

	DynamicLibrary * library = 0;
	const LibraryMap::iterator libraryInstance( libraries_.find( libName ) );
	if ( libraryInstance != libraries_.end() )
	{
		library = libraryInstance -> second;
	}
	else
	{
		library = new DynamicLibrary();
		libraries_[ libName ] = library;
		if ( ( library ) && ( !library -> Open( libName, true ) ) )
		{
			// This is the first time we try to load this library.
			// We are able to specify the reason of failure.
			throw LoaderException( pdl_string( "Cannot load library `" ) +
			                       pdl_string( libName ) + pdl_string( "`: " ) +
			                       library -> GetLastError() );
		}
	}
	
	if ( !library )
	{
		// Actually, this should never happen.
		// If it has happened, this means serious memory damage
		throw LoaderException( pdl_string( "Internal error" ) );
	}

	return ( *library );
}