Emmanuel BENOîT
30d8d3057e
* Makefile changes allowing for cross-compilation * SRDData: had to rename an enum member from ERROR to ERR because apparently creating a macro called ERROR is a thing in the windows headers * DynLib: ported * Strings: fixes in toOSString, untested for now * Fixes in some tests * TODO list update
206 lines
4.5 KiB
C++
206 lines
4.5 KiB
C++
/******************************************************************************/
|
|
/* DYNAMIC LIBRARIES **********************************************************/
|
|
/******************************************************************************/
|
|
|
|
#include <ebcl/DynLib.hh>
|
|
#include <ebcl/Threading.hh>
|
|
using namespace ebcl;
|
|
|
|
#ifdef _WIN32
|
|
|
|
/*= T_DynLibWindows ==========================================================*/
|
|
|
|
namespace {
|
|
struct T_DynLibWindows_
|
|
{
|
|
T_Buffer< char > path;
|
|
T_String error;
|
|
HMODULE lib;
|
|
|
|
explicit T_DynLibWindows_( T_String const& path ) noexcept;
|
|
explicit T_DynLibWindows_( char const* const path ) noexcept;
|
|
~T_DynLibWindows_( ) noexcept;
|
|
|
|
bool load( ) noexcept;
|
|
void unload( ) noexcept;
|
|
|
|
bool isLoaded( ) const noexcept;
|
|
|
|
void* getSymbol( char const* const symbol ) noexcept;
|
|
};
|
|
} // namespace
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
inline T_DynLibWindows_::T_DynLibWindows_(
|
|
T_String const& path ) noexcept
|
|
: path( path.toOSString( ) ) , lib( nullptr )
|
|
{ }
|
|
|
|
inline T_DynLibWindows_::T_DynLibWindows_(
|
|
char const* const path ) noexcept
|
|
: path( path , strlen( path ) ) , lib( nullptr )
|
|
{ }
|
|
|
|
inline T_DynLibWindows_::~T_DynLibWindows_( ) noexcept
|
|
{
|
|
unload( );
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
inline bool T_DynLibWindows_::load( ) noexcept
|
|
{
|
|
lib = LoadLibraryW( (wchar_t const*) path.data( ) );
|
|
return lib != nullptr;
|
|
}
|
|
|
|
inline void T_DynLibWindows_::unload( ) noexcept
|
|
{
|
|
if ( lib != nullptr ) {
|
|
FreeLibrary( lib );
|
|
lib = nullptr;
|
|
}
|
|
}
|
|
|
|
inline bool T_DynLibWindows_::isLoaded( ) const noexcept
|
|
{
|
|
return lib != nullptr;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
inline void* T_DynLibWindows_::getSymbol(
|
|
char const* const symbol ) noexcept
|
|
{
|
|
return (void*) GetProcAddress( lib , symbol );
|
|
}
|
|
|
|
using T_DynLibImpl_ = T_DynLibWindows_;
|
|
|
|
|
|
#else // ifdef _WIN32
|
|
|
|
/*= T_DynLibLinux_ ===========================================================*/
|
|
|
|
#include <dlfcn.h>
|
|
#include <atomic>
|
|
|
|
namespace {
|
|
struct T_DynLibLinux_
|
|
{
|
|
T_Buffer< char > path;
|
|
T_String error;
|
|
void* lib;
|
|
|
|
explicit T_DynLibLinux_( T_String const& path ) noexcept;
|
|
explicit T_DynLibLinux_( char const* const path ) noexcept;
|
|
~T_DynLibLinux_( ) noexcept;
|
|
|
|
bool load( ) noexcept;
|
|
void unload( ) noexcept;
|
|
|
|
bool isLoaded( ) const noexcept;
|
|
|
|
void* getSymbol( char const* const symbol ) noexcept;
|
|
};
|
|
} // namespace
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
inline T_DynLibLinux_::T_DynLibLinux_(
|
|
T_String const& path ) noexcept
|
|
: path( path.toOSString( ) ) , lib( nullptr )
|
|
{ }
|
|
|
|
inline T_DynLibLinux_::T_DynLibLinux_(
|
|
char const* const path ) noexcept
|
|
: path( path , strlen( path ) ) , lib( nullptr )
|
|
{ }
|
|
|
|
inline T_DynLibLinux_::~T_DynLibLinux_( ) noexcept
|
|
{
|
|
unload( );
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
inline bool T_DynLibLinux_::load( ) noexcept
|
|
{
|
|
if ( lib != nullptr ) {
|
|
return true;
|
|
}
|
|
lib = dlopen( &path[ 0 ] , RTLD_LOCAL | RTLD_NOW );
|
|
error = lib ? T_String{} : T_String{ dlerror( ) };
|
|
return lib != nullptr;
|
|
}
|
|
|
|
inline void T_DynLibLinux_::unload( ) noexcept
|
|
{
|
|
if ( lib != nullptr ) {
|
|
dlclose( lib );
|
|
lib = nullptr;
|
|
}
|
|
}
|
|
|
|
inline bool T_DynLibLinux_::isLoaded( ) const noexcept
|
|
{
|
|
return lib != nullptr;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
inline void* T_DynLibLinux_::getSymbol(
|
|
char const* const symbol ) noexcept
|
|
{
|
|
assert( lib != nullptr );
|
|
void* const ptr( dlsym( lib , symbol ) );
|
|
error = ( ptr == nullptr ) ? T_String{ dlerror( ) } : T_String{};
|
|
return ptr;
|
|
}
|
|
|
|
using T_DynLibImpl_ = T_DynLibLinux_;
|
|
|
|
#endif // ifdef _WIN32
|
|
|
|
/*= T_DynLib =================================================================*/
|
|
|
|
T_DynLib::T_DynLib(
|
|
T_String const& name )
|
|
: A_PrivateImplementation( new T_DynLibImpl_( name ) )
|
|
{ }
|
|
|
|
T_DynLib::T_DynLib(
|
|
char const* const name )
|
|
: A_PrivateImplementation( new T_DynLibImpl_( name ) )
|
|
{ }
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
bool T_DynLib::load( )
|
|
{
|
|
return p< T_DynLibImpl_ >( ).load( );
|
|
}
|
|
|
|
void T_DynLib::unload( )
|
|
{
|
|
p< T_DynLibImpl_ >( ).unload( );
|
|
}
|
|
|
|
bool T_DynLib::isLoaded( ) const noexcept
|
|
{
|
|
return p< T_DynLibImpl_ >( ).isLoaded( );
|
|
}
|
|
|
|
T_String T_DynLib::lastError( ) const noexcept
|
|
{
|
|
return p< T_DynLibImpl_ >( ).error;
|
|
}
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
void* T_DynLib::getRawSymbol(
|
|
char const* const name ) const noexcept
|
|
{
|
|
return p< T_DynLibImpl_ >( ).getSymbol( name );
|
|
}
|