view C++/DynLib.h @ 196:274b4f216e65

DynLib: Windows support complete
author David Demelier <markand@malikania.fr>
date Thu, 28 Nov 2013 20:03:07 +0100
parents 42b77e0161d0
children 0b029b53ff55
line wrap: on
line source

/*
 * 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>

#if defined(_MSC_VER)
#  include <Windows.h>
#endif

/**
 * @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)
	using Handle	= HMODULE;
	using Sym	= FARPROC;
#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_