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

Last change on this file since 319 was 319, checked in by epyon, 11 years ago
  • created core module and moved all free source files there
  • took the opportunity to update all copyright lines and minor cleanup
  • minor fixes
  • not all examples are up to date
File size: 3.7 KB
Line 
1// Copyright (C) 2012-2014 ChaosForge Ltd
2// This file is part of NV Libraries.
3// For conditions of distribution and use, see copyright notice in nv.hh
4#include "nv/core/common.hh"
5#include "nv/core/library.hh"
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 )
15#elif NV_PLATFORM == NV_LINUX || NV_PLATFORM == NV_APPLE
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
32#include "nv/core/logging.hh"
33
34using namespace nv;
35
36library::library()
37    : m_handle( nullptr ), m_name()
38{
39}
40
41void library::open( const string& name )
42{
43        m_name = name;
44        if ( !open() )
45        {
46                m_handle = nullptr;
47                NV_THROW( library_error, "Can't load library!", name );
48        }
49}
50
51bool nv::library::try_open( const string& name )
52{
53        m_name = name;
54        if ( !open() )
55        {
56                m_handle = nullptr;
57                return false;
58        }
59        return true;
60}
61
62const string& library::get_name() const
63{
64    return m_name;
65}
66
67bool library::open( )
68{
69    if ( m_handle != NULL )
70    {
71        return true;
72    }
73    NV_LOG( LOG_NOTICE, "library : loading '" + m_name + "'..." );
74
75    string name = m_name;
76    string ext  = NV_LIB_EXT;
77    size_t ext_len   = ext.length();
78
79    if ( name.length() < ext_len || name.substr( name.length() - ext_len, ext_len ) != ext )
80    {
81        name += ext;
82    }
83
84    m_handle = (void*)NV_LIB_OPEN( name.c_str() );
85
86    if ( m_handle == NULL )
87    {
88                NV_LOG( LOG_NOTICE, "library : '" + name + "' failed to open." );
89                return false;
90    }
91    NV_LOG( LOG_NOTICE, "library : '" + name + "' loaded." );
92        return true;
93}
94
95void* library::get( const string& symbol )
96{
97        void* result = (void*) NV_LIB_GET( (NV_LIB_HANDLE) m_handle, symbol.c_str() );
98    if ( !result )
99    {
100        NV_THROW( library_error, "Can't find symbol " + symbol + "!", m_name );
101    }
102        return result;
103}
104
105void* nv::library::try_get( const string& symbol )
106{
107        return (void*) NV_LIB_GET( (NV_LIB_HANDLE) m_handle, symbol.c_str() );
108}
109
110bool library::is_open() const
111{
112        return m_handle != nullptr;
113}
114
115void library::close()
116{
117    if ( NV_LIB_CLOSE( (NV_LIB_HANDLE)m_handle ) )
118    {
119        NV_LOG( LOG_ERROR, "library : can't close library '" + m_name + "'!" );
120    }
121    m_handle = NULL;
122}
123
124library::~library()
125{
126    if ( m_handle != NULL )
127    {
128        close();
129    }
130}
131
132string library::get_error()
133{
134#if NV_PLATFORM == NV_WINDOWS
135    // We do hate WinAPI for code like this, don't we?
136    LPTSTR buffer = NULL;
137    FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
138        NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &buffer, 0, NULL );
139    string msg( (char*)buffer );
140    LocalFree( buffer );
141    return msg;
142#elif NV_PLATFORM == NV_LINUX || NV_PLATFORM == NV_APPLE
143    return string(dlerror());
144#else
145    return string("");
146#endif
147}
Note: See TracBrowser for help on using the repository browser.