summaryrefslogtreecommitdiffstats
path: root/lib/base/library.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/base/library.cpp')
-rw-r--r--lib/base/library.cpp68
1 files changed, 68 insertions, 0 deletions
diff --git a/lib/base/library.cpp b/lib/base/library.cpp
new file mode 100644
index 0000000..541ed74
--- /dev/null
+++ b/lib/base/library.cpp
@@ -0,0 +1,68 @@
+/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
+
+#include "base/library.hpp"
+#include "base/loader.hpp"
+#include "base/logger.hpp"
+#include "base/exception.hpp"
+#include "base/application.hpp"
+
+using namespace icinga;
+
+/**
+ * Loads the specified library.
+ *
+ * @param name The name of the library.
+ */
+Library::Library(const String& name)
+{
+ String path;
+#if defined(_WIN32)
+ path = name + ".dll";
+#elif defined(__APPLE__)
+ path = "lib" + name + "." + Application::GetAppSpecVersion() + ".dylib";
+#else /* __APPLE__ */
+ path = "lib" + name + ".so." + Application::GetAppSpecVersion();
+#endif /* _WIN32 */
+
+ Log(LogNotice, "Library")
+ << "Loading library '" << path << "'";
+
+#ifdef _WIN32
+ HMODULE hModule = LoadLibrary(path.CStr());
+
+ if (!hModule) {
+ BOOST_THROW_EXCEPTION(win32_error()
+ << boost::errinfo_api_function("LoadLibrary")
+ << errinfo_win32_error(GetLastError())
+ << boost::errinfo_file_name(path));
+ }
+#else /* _WIN32 */
+ void *hModule = dlopen(path.CStr(), RTLD_NOW | RTLD_GLOBAL);
+
+ if (!hModule) {
+ BOOST_THROW_EXCEPTION(std::runtime_error("Could not load library '" + path + "': " + dlerror()));
+ }
+#endif /* _WIN32 */
+
+ Loader::ExecuteDeferredInitializers();
+
+ m_Handle.reset(new LibraryHandle(hModule), [](LibraryHandle *handle) {
+#ifdef _WIN32
+ FreeLibrary(*handle);
+#else /* _WIN32 */
+ dlclose(*handle);
+#endif /* _WIN32 */
+ });
+}
+
+void *Library::GetSymbolAddress(const String& name) const
+{
+ if (!m_Handle)
+ BOOST_THROW_EXCEPTION(std::runtime_error("Invalid library handle"));
+
+#ifdef _WIN32
+ return GetProcAddress(*m_Handle.get(), name.CStr());
+#else /* _WIN32 */
+ return dlsym(*m_Handle.get(), name.CStr());
+#endif /* _WIN32 */
+}