source: trunk/src/library.cc @ 27

Last change on this file since 27 was 14, checked in by melon, 12 years ago

Header included to put compilation on Linux through

File size: 3.3 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
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( const std::string& name )
39    : m_name( name )
40{
41    m_handle = NULL;
42    open();
43}
44
45void library::open( const std::string& name )
46{
47        m_name = name;
48        open();
49}
50
51const std::string& library::get_name() const
52{
53    return m_name;
54}
55
56void library::open()
57{
58    if ( m_handle != NULL )
59    {
60        return;
61    }
62    NV_LOG( LOG_NOTICE, "library : loading '" + m_name + "'..." );
63
64    std::string name = m_name;
65    std::string ext  = NV_LIB_EXT;
66    size_t ext_len   = ext.length();
67
68    if ( name.length() < ext_len || name.substr( name.length() - ext_len, ext_len ) != ext )
69    {
70        name += ext;
71    }
72
73    m_handle = (void*)NV_LIB_OPEN( name.c_str() );
74
75    if ( m_handle == NULL )
76    {
77        throw library_error( "Can't load library!", name );
78    }
79    NV_LOG( LOG_NOTICE, "library : '" + name + "' loaded." );
80}
81
82void* library::get( const std::string& symbol )
83{
84        void* result = (void*) NV_LIB_GET( (NV_LIB_HANDLE) m_handle, symbol.c_str() );
85    if ( !result )
86    {
87        throw library_error( "Can't find symbol " + symbol + "!", m_name );
88    }
89        return result;
90}
91
92
93
94void library::close()
95{
96    if ( NV_LIB_CLOSE( (NV_LIB_HANDLE)m_handle ) )
97    {
98        NV_LOG( LOG_ERROR, "library : can't close library '" + m_name + "'!" );
99    }
100    m_handle = NULL;
101    NV_LOG( LOG_NOTICE, "library : '" + m_name + "' closed." );
102}
103
104library::~library()
105{
106    if ( m_handle != NULL )
107    {
108        close();
109    }
110}
111
112std::string library::get_error()
113{
114#if NV_PLATFORM == NV_WINDOWS
115    // We do hate WinAPI for code like this, don't we?
116    LPVOID buffer;
117    FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
118        NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &buffer, 0, NULL );
119    std::string msg( (char*)buffer );
120    LocalFree( buffer );
121    return msg;
122#elif NV_PLATFORM == NV_LINUX || NV_PLATFORM == NV_APPLE
123    return std::string(dlerror());
124#else
125    return std::string("");
126#endif
127}
Note: See TracBrowser for help on using the repository browser.