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
Line 
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
7#include "nv/core/library.hh"
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_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 )
16#elif NV_PLATFORM == NV_LINUX || NV_PLATFORM == NV_APPLE
17#   include <dlfcn.h>
18#   define NV_LIB_EXT ".so"
19#   define NV_LIB_OPEN( name ) dlopen( name, RTLD_LAZY | RTLD_GLOBAL)
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 )
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 )
28#   define NV_LIB_CLOSE( handle ) ( mac_unloadExeBundle( handle ) == 0 )
29#endif
30
31#include "nv/core/logging.hh"
32
33using namespace nv;
34
35library::library()
36    : m_handle( nullptr ), m_name()
37{
38}
39
40void library::open( string_view name )
41{
42        m_name.assign( name.data(), name.size() );
43        if ( !open() )
44        {
45                m_handle = nullptr;
46                NV_THROW( library_error, "Can't load library!", name.data() );
47        }
48}
49
50bool nv::library::try_open( string_view name )
51{
52        m_name.assign( name.data(), name.size() );
53        if ( !open() )
54        {
55                m_handle = nullptr;
56                return false;
57        }
58        return true;
59}
60
61string_view library::get_name() const
62{
63    return string_view( m_name );
64}
65
66bool library::open( )
67{
68    if ( m_handle != NULL )
69    {
70        return true;
71    }
72    NV_LOG_NOTICE( "library : loading '", m_name, "'..." );
73
74        std::string name = m_name;
75        string_view ext( NV_LIB_EXT );
76
77        if ( name.length() < ext.length() || name.substr( name.length() - ext.length(), ext.length() ) != ext )
78    {
79        name.append( ext.data(), ext.length() );
80    }
81
82    m_handle = NV_LIB_OPEN( name.c_str() );
83
84    if ( m_handle == NULL )
85    {
86                NV_LOG_NOTICE( "library : '", name, "' failed to open." );
87                return false;
88    }
89    NV_LOG_NOTICE( "library : '", name, "' loaded." );
90        return true;
91}
92
93void* library::get( string_view symbol )
94{
95        void* result = NV_LIB_GET( m_handle, symbol.data() );
96    if ( !result )
97    {
98        NV_THROW( library_error, "Can't find symbol " + std::string(symbol.data(),symbol.size()) + "!", m_name );
99    }
100        return result;
101}
102
103void* nv::library::try_get( string_view symbol )
104{
105        return NV_LIB_GET( m_handle, symbol.data() );
106}
107
108bool library::is_open() const
109{
110        return m_handle != nullptr;
111}
112
113void library::close()
114{
115    if ( ! NV_LIB_CLOSE( m_handle ) )
116    {
117        NV_LOG_ERROR( "library : can't close library '", m_name, "'!" );
118    }
119    m_handle = nullptr;
120}
121
122library::~library()
123{
124    if ( m_handle != nullptr )
125    {
126        close();
127    }
128}
129
130std::string library::get_error()
131{
132#if NV_PLATFORM == NV_WINDOWS
133    // We do hate WinAPI for code like this, don't we?
134    LPTSTR buffer = nullptr;
135    FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
136        NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), reinterpret_cast<LPTSTR>( &buffer ), 0, NULL );
137    std::string msg( reinterpret_cast<char*>( buffer ) );
138    LocalFree( buffer );
139    return msg;
140#elif NV_PLATFORM == NV_LINUX || NV_PLATFORM == NV_APPLE
141    return std::string( dlerror() );
142#else
143    return std::string("");
144#endif
145}
Note: See TracBrowser for help on using the repository browser.