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

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