1 #ifndef _library__loadlib__hpp__included__
2 #define _library__loadlib__hpp__included__
10 #if defined(_WIN32) || defined(_WIN64)
16 threads::lock
& global_mutex();
25 * Construct a NULL library.
34 * Parameter filename: The name of file.
35 * Throws std::bad_alloc: Not enough memory.
36 * Throws std::runtime_error: Error loading shared library.
38 library(const std::string
& filename
) throw(std::bad_alloc
, std::runtime_error
)
42 lib
= new internal(filename
);
54 threads::alock
h(global_mutex());
55 if(lib
&& !--lib
->refs
)
61 * Parameter symbol: The symbol to look up.
62 * Returns: The symbol value.
63 * Throws std::bad_alloc: Not enough memory.
64 * Throws std::runtime_error: Error looking up the symbol.
66 void* operator[](const std::string
& symbol
) const throw(std::bad_alloc
, std::runtime_error
)
68 threads::alock
h(global_mutex());
69 if(!lib
) throw std::runtime_error("Symbol '" + symbol
+ "' not found");
70 return (*lib
)[symbol
];
73 * See what libraries are called on this platform.
75 * Returns: The name of library.
77 static const std::string
& name() throw();
79 * See what standard library extension is on this platform.
81 * Returns: The extension of library.
83 static const std::string
& extension() throw();
87 library(const library
& r
)
89 threads::alock
h(global_mutex());
93 library
& operator=(const library
& r
)
97 threads::alock
h(global_mutex());
98 if(lib
&& !--lib
->refs
)
104 std::string
get_libname() const { return lib
->libname
; }
105 void mark(const void* obj
) const { if(lib
) lib
->mark(obj
); }
106 bool is_marked(const void* obj
) const { return lib
? lib
->is_marked(obj
) : false; }
108 * Get currently loading library, or NULL if nothing is loading.
110 static library
* loading() throw();
112 void set_loading(library
* lib
) throw(std::bad_alloc
);
115 internal(const std::string
& filename
) throw(std::bad_alloc
, std::runtime_error
);
117 void* operator[](const std::string
& symbol
) const throw(std::bad_alloc
, std::runtime_error
);
118 internal(const internal
&);
119 internal
& operator=(const internal
&);
120 #if defined(_WIN32) || defined(_WIN64)
122 #elif !defined(NO_DLFCN)
127 void mark(const void* obj
) { marked
.insert(obj
); }
128 bool is_marked(const void* obj
) { return marked
.count(obj
); }
129 std::set
<const void*> marked
;
131 mutable internal
* lib
;
139 template<typename T
, typename
... U
> struct fntype
{ typedef T(*t
)(U
...); };
150 * Construct a module from list of symbols.
152 module(std::initializer_list
<symbol
> symbols
, std::function
<void(const module
&)> init_fn
);
154 * Construct a module from library.
160 module(const module
& mod
);
168 void* operator[](const std::string
& symbol
) const throw(std::bad_alloc
, std::runtime_error
);
170 * Variable symbol lookup.
172 template<typename T
> T
* var(const std::string
& symbol
) const throw(std::bad_alloc
, std::runtime_error
)
174 return (T
*)(*this)[symbol
];
177 * Function symbol lookup.
179 template<typename T
, typename
... U
> typename fntype
<T
, U
...>::t
fn(const std::string
& symbol
) const
180 throw(std::bad_alloc
, std::runtime_error
)
182 return (typename fntype
<T
, U
...>::t
)(*this)[symbol
];
187 std::string
get_libname() const { return libname
; }
189 * Run all not ran initialization functions.
191 static void run_initializers();
193 * Mark object (only works for libraries).
195 void mark(const void* obj
) const { if(dynamic
) lib
.mark(obj
); }
197 * Is object marked (only works for libraries)?
199 bool is_marked(const void* obj
) const { return dynamic
? lib
.is_marked(obj
) : false; }
203 std::map
<std::string
, void*> symbols
;
204 std::function
<void(const module
&)> init
;