source: trunk/src/core/library.cc @ 437

Last change on this file since 437 was 437, checked in by epyon, 10 years ago
  • local updates (string removal)
File size: 3.8 KB
RevLine 
[395]1// Copyright (C) 2012-2015 ChaosForge Ltd
2// http://chaosforge.org/
3//
4// This file is part of Nova libraries.
5// For conditions of distribution and use, see copying.txt file in root folder.
6
[319]7#include "nv/core/library.hh"
[437]8#include <string>
[4]9
10#if NV_PLATFORM == NV_WINDOWS
11#   define WIN32_LEAN_AND_MEAN
12#   include <windows.h>
13#   define NV_LIB_EXT ".dll"
[402]14#   define NV_LIB_OPEN( name ) static_cast<void*>( LoadLibraryEx( name, NULL, LOAD_WITH_ALTERED_SEARCH_PATH ) )
15#   define NV_LIB_GET( handle, name ) reinterpret_cast<void*>( GetProcAddress( static_cast<HMODULE>( handle ), name ) )
16#   define NV_LIB_CLOSE( handle ) ( FreeLibrary( static_cast<HMODULE>( handle ) ) != 0 )
[113]17#elif NV_PLATFORM == NV_LINUX || NV_PLATFORM == NV_APPLE
[4]18#   include <dlfcn.h>
19#   define NV_LIB_EXT ".so"
20#   define NV_LIB_OPEN( name ) dlopen( name, RTLD_LAZY | RTLD_GLOBAL)
[402]21#   define NV_LIB_GET( handle, name ) dlsym( static_cast<void*>( handle ), name )
22#   define NV_LIB_CLOSE( handle ) ( dlclose( static_cast<void*>( handle ) ) == 0 )
[4]23#elif NV_PLATFORM == NV_APPLE
24#   include "macUtils.h"
25#   include <dlfcn.h>
26#   define NV_LIB_EXT ".dylib"
27#   define NV_LIB_OPEN( name ) mac_loadExeBundle( name )
28#   define NV_LIB_GET( handle, name ) mac_getBundleSym( handle, name )
[402]29#   define NV_LIB_CLOSE( handle ) ( mac_unloadExeBundle( handle ) == 0 )
[4]30#endif
31
[319]32#include "nv/core/logging.hh"
[4]33
34using namespace nv;
35
[109]36library::library()
[121]37    : m_handle( nullptr ), m_name()
[4]38{
39}
40
[399]41void library::open( string_view name )
[4]42{
[437]43        m_name = name;
[166]44        if ( !open() )
45        {
46                m_handle = nullptr;
[403]47                NV_LOG_CRITICAL( "library \"", name, "\" : failed to load!" );
48                NV_ABORT( "Can't load library!" );
[166]49        }
[4]50}
51
[399]52bool nv::library::try_open( string_view name )
[166]53{
[437]54        m_name = name;
[166]55        if ( !open() )
56        {
57                m_handle = nullptr;
58                return false;
59        }
60        return true;
61}
62
[399]63string_view library::get_name() const
[4]64{
[437]65    return m_name;
[4]66}
67
[166]68bool library::open( )
[4]69{
70    if ( m_handle != NULL )
71    {
[166]72        return true;
[4]73    }
[437]74    NV_LOG_NOTICE( "library \"", m_name, "\" : loading..." );
[4]75
[437]76        std::string name( m_name.data(), m_name.length() );
[433]77        std::string ext( NV_LIB_EXT );
[4]78
[380]79        if ( name.length() < ext.length() || name.substr( name.length() - ext.length(), ext.length() ) != ext )
[4]80    {
[380]81        name.append( ext.data(), ext.length() );
[4]82    }
83
[402]84    m_handle = NV_LIB_OPEN( name.c_str() );
[4]85
86    if ( m_handle == NULL )
87    {
[437]88                NV_LOG_NOTICE( "library \"", m_name, "\" : failed to open!" );
[166]89                return false;
[4]90    }
[166]91        return true;
[4]92}
93
[399]94void* library::get( string_view symbol )
[4]95{
[402]96        void* result = NV_LIB_GET( m_handle, symbol.data() );
[4]97    if ( !result )
98    {
[437]99                NV_LOG_CRITICAL( "library \"", m_name, "\" : can't find symbol \"", symbol, "\"" );
[403]100                NV_ABORT( "Library symbol load failed!" );
[4]101    }
102        return result;
103}
104
[399]105void* nv::library::try_get( string_view symbol )
[166]106{
[402]107        return NV_LIB_GET( m_handle, symbol.data() );
[166]108}
109
[109]110bool library::is_open() const
111{
112        return m_handle != nullptr;
113}
[4]114
115void library::close()
116{
[402]117    if ( ! NV_LIB_CLOSE( m_handle ) )
[4]118    {
[437]119        NV_LOG_ERROR( "library \"", m_name, "\" : can't close library!" );
[4]120    }
[402]121    m_handle = nullptr;
[4]122}
123
124library::~library()
125{
[402]126    if ( m_handle != nullptr )
[4]127    {
128        close();
129    }
130}
131
[437]132nv::string_view library::get_error()
[4]133{
134#if NV_PLATFORM == NV_WINDOWS
135    // We do hate WinAPI for code like this, don't we?
[437]136        static TCHAR buffer[256];
137    FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
138        NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), reinterpret_cast<LPTSTR>( &buffer ), 256, NULL );
139    return string_view( reinterpret_cast<char*>( buffer ) );
[4]140#elif NV_PLATFORM == NV_LINUX || NV_PLATFORM == NV_APPLE
[437]141    return nv::string_view( dlerror() );
[4]142#else
[437]143    return nv::string_view();
[4]144#endif
145}
Note: See TracBrowser for help on using the repository browser.