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

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