changeset 195:42b77e0161d0

Add a dynamic library loader
author David Demelier <markand@malikania.fr>
date Wed, 27 Nov 2013 21:20:26 +0100
parents 9fc5f917872b
children 274b4f216e65
files C++/DynLib.cpp C++/DynLib.h
diffstat 2 files changed, 200 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/C++/DynLib.cpp	Wed Nov 27 21:20:26 2013 +0100
@@ -0,0 +1,105 @@
+/*
+ * DynLib.cpp -- portable shared library loader
+ *
+ * Copyright (c) 2013 David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <stdexcept>
+
+#if defined(_MSC_VER)
+#  include <Windows.h>
+#else
+#  include <dlfcn.h>
+#endif
+
+#include "DynLib.h"
+
+#if defined(_MSC_VER)
+
+void DynLib::systemInit()
+{
+	// TODO: Windows
+}
+
+DynLib::Handle DynLib::systemLoad(const std::string &path, Policy policy);
+{
+	// TODO: Windows
+}
+
+DynLib::Sym DynLib::systemSym(const std::string &name)
+{
+	// TODO: Windows
+}
+
+void DynLib::systemClose()
+{
+	// TODO: Windows
+}
+
+#else
+
+void DynLib::systemInit()
+{
+	m_handle = nullptr;
+}
+
+DynLib::Handle DynLib::systemLoad(const std::string &path, Policy policy) const
+{
+	int mode = (policy == Immediately) ? RTLD_NOW : RTLD_LAZY;
+	Handle handle;
+
+	handle = dlopen(path.c_str(), mode);
+	if (handle == nullptr)
+		throw std::runtime_error(dlerror());
+
+	return handle;
+}
+
+DynLib::Sym DynLib::systemSym(const std::string &name)
+{
+	Sym sym;
+
+	if (m_handle == nullptr)
+		throw std::runtime_error("library not loaded");
+
+	sym = dlsym(m_handle, name.c_str());
+	if (sym == nullptr)
+		throw std::out_of_range(dlerror());
+
+	return sym;
+}
+
+void DynLib::systemClose()
+{
+	if (m_handle != nullptr)
+		dlclose(m_handle);
+}
+
+#endif
+
+DynLib::DynLib()
+{
+	systemInit();
+}
+
+DynLib::DynLib(const std::string &path, Policy policy)
+{
+	m_handle = systemLoad(path, policy);
+}
+
+DynLib::~DynLib()
+{
+	systemClose();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/C++/DynLib.h	Wed Nov 27 21:20:26 2013 +0100
@@ -0,0 +1,95 @@
+/*
+ * DynLib.h -- portable shared library loader
+ *
+ * Copyright (c) 2013 David Demelier <markand@malikania.fr>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _DYN_LIB_H_
+#define _DYN_LIB_H_
+
+#include <string>
+
+/**
+ * @class DynLib
+ * @brief Load a dynamic module
+ *
+ * This class is a portable wrapper to load shared libraries on
+ * supported systems.
+ */
+class DynLib {
+public:
+#if defined(_MSC_VER)
+#else
+	using Handle	= void *;
+	using Sym	= void *;
+#endif
+
+	enum Policy {
+		Immediately,		//! load symbols immediately
+		Lazy			//! load symbols when needed
+	};
+
+private:
+	Handle	m_handle;
+
+	void	systemInit();
+	Handle	systemLoad(const std::string &path, Policy policy) const;
+	Sym	systemSym(const std::string &name);
+	void	systemClose();
+
+public:
+	/**
+	 * Copy is forbidden.
+	 */
+	DynLib(const DynLib &) = delete;
+	DynLib &operator=(const DynLib &) = delete;
+
+	/**
+	 * Default constructor.
+	 */
+	DynLib();
+
+	/**
+	 * Constructor to load a shared module. The path must
+	 * be absolute.
+	 *
+	 * @param path the absolute path
+	 * @param policy the policy to load
+	 * @throw std::runtime_error on error
+	 */
+	DynLib(const std::string &path,
+	       Policy policy = Immediately);
+
+	/**
+	 * Close the library automatically.
+	 */
+	~DynLib();
+
+	/**
+	 * Get a symbol from the library.
+	 *
+	 * @param name the symbol
+	 * @return the symbol
+	 * @throw std::runtime_error on error
+	 * @throw std::out_of_range if not found
+	 */
+	template <typename T>
+	T sym(const std::string &name)
+	{
+		return reinterpret_cast<T>(systemSym(name));
+	}
+};
+
+#endif // !_DYN_LIB_H_