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

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