source: trunk/src/library.cc @ 120

Last change on this file since 120 was 120, checked in by epyon, 12 years ago
  • Nova now properly compiles and works under: mingw GCC 4.6 32-bit target mingw GCC 4.6 64-bit targte clang 3.2 32-bit target (64-bit clang doesn't work under windows)
  • warning removal will follow soon
File size: 3.4 KB
Line 
1// Copyright (C) 2012 Kornel Kisielewicz
2// This file is part of NV Libraries.
3// For conditions of distribution and use, see copyright notice in nv.hh
4#include "nv/common.hh"
5#include "nv/library.hh"
6
7#include <string.h>
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 )
17#elif NV_PLATFORM == NV_LINUX || NV_PLATFORM == NV_APPLE
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
34#include "nv/logging.hh"
35
36using namespace nv;
37
38library::library()
39    : m_name(), m_handle( nullptr )
40{
41}
42
43void library::open( const std::string& name )
44{
45        m_name = name;
46        open();
47}
48
49const std::string& library::get_name() const
50{
51    return m_name;
52}
53
54void library::open()
55{
56    if ( m_handle != NULL )
57    {
58        return;
59    }
60    NV_LOG( LOG_NOTICE, "library : loading '" + m_name + "'..." );
61
62    std::string name = m_name;
63    std::string ext  = NV_LIB_EXT;
64    size_t ext_len   = ext.length();
65
66    if ( name.length() < ext_len || name.substr( name.length() - ext_len, ext_len ) != ext )
67    {
68        name += ext;
69    }
70
71    m_handle = (void*)NV_LIB_OPEN( name.c_str() );
72
73    if ( m_handle == NULL )
74    {
75        NV_THROW( library_error, "Can't load library!", name );
76    }
77    NV_LOG( LOG_NOTICE, "library : '" + name + "' loaded." );
78}
79
80void* library::get( const std::string& symbol )
81{
82        void* result = (void*) NV_LIB_GET( (NV_LIB_HANDLE) m_handle, symbol.c_str() );
83    if ( !result )
84    {
85        NV_THROW( library_error, "Can't find symbol " + symbol + "!", m_name );
86    }
87        return result;
88}
89
90bool library::is_open() const
91{
92        return m_handle != nullptr;
93}
94
95void library::close()
96{
97    if ( NV_LIB_CLOSE( (NV_LIB_HANDLE)m_handle ) )
98    {
99        NV_LOG( LOG_ERROR, "library : can't close library '" + m_name + "'!" );
100    }
101    m_handle = NULL;
102    NV_LOG( LOG_NOTICE, "library : '" + m_name + "' closed." );
103}
104
105library::~library()
106{
107    if ( m_handle != NULL )
108    {
109        close();
110    }
111}
112
113std::string library::get_error()
114{
115#if NV_PLATFORM == NV_WINDOWS
116    // We do hate WinAPI for code like this, don't we?
117    LPTSTR buffer = NULL;
118    FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
119        NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &buffer, 0, NULL );
120    std::string msg( (char*)buffer );
121    LocalFree( buffer );
122    return msg;
123#elif NV_PLATFORM == NV_LINUX || NV_PLATFORM == NV_APPLE
124    return std::string(dlerror());
125#else
126    return std::string("");
127#endif
128}
Note: See TracBrowser for help on using the repository browser.