⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 classloader.h

📁 C++ class libraries for network-centric, portable applications, integrated perfectly with the C++ St
💻 H
字号:
//// ClassLoader.h//// $Id: //poco/1.2/Foundation/include/Poco/ClassLoader.h#1 $//// Library: Foundation// Package: SharedLibrary// Module:  ClassLoader//// Definition of the ClassLoader class.//// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.// and Contributors.//// Permission is hereby granted, free of charge, to any person or organization// obtaining a copy of the software and accompanying documentation covered by// this license (the "Software") to use, reproduce, display, distribute,// execute, and transmit the Software, and to prepare derivative works of the// Software, and to permit third-parties to whom the Software is furnished to// do so, all subject to the following:// // The copyright notices in the Software and this entire statement, including// the above license grant, this restriction and the following disclaimer,// must be included in all copies of the Software, in whole or in part, and// all derivative works of the Software, unless such copies or derivative// works are solely in the form of machine-executable object code generated by// a source language processor.// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER// DEALINGS IN THE SOFTWARE.//#ifndef Foundation_ClassLoader_INCLUDED#define Foundation_ClassLoader_INCLUDED#include "Poco/Foundation.h"#include "Poco/MetaObject.h"#include "Poco/Manifest.h"#include "Poco/SharedLibrary.h"#include "Poco/Mutex.h"#include "Poco/Exception.h"#include <map>namespace Poco {template <class Base>class ClassLoader	/// The ClassLoader loads C++ classes from shared libraries	/// at runtime. It must be instantiated with a root class	/// of the loadable classes.	/// For a class to be loadable from a library, the library	/// must provide a Manifest of all the classes it contains.	/// The Manifest for a shared library can be easily built	/// with the help of the macros in the header file	/// "Foundation/ClassLibrary.h".{public:	typedef AbstractMetaObject<Base> Meta;	typedef Manifest<Base> Manif;	typedef void (*InitializeLibraryFunc)();	typedef void (*UninitializeLibraryFunc)();	typedef bool (*BuildManifestFunc)(ManifestBase*);	struct LibraryInfo	{		SharedLibrary* pLibrary;		const Manif*   pManifest;		int            refCount;	};	typedef std::map<std::string, LibraryInfo> LibraryMap;	class Iterator		/// The ClassLoader's very own iterator class.	{	public:		typedef std::pair<std::string, const Manif*> Pair;		Iterator(const typename LibraryMap::const_iterator& it)		{			_it = it;		}		Iterator(const Iterator& it)		{			_it = it._it;		}		~Iterator()		{		}		Iterator& operator = (const Iterator& it)		{			_it = it._it;			return *this;		}		inline bool operator == (const Iterator& it) const		{			return _it == it._it;		}		inline bool operator != (const Iterator& it) const		{			return _it != it._it;		}		Iterator& operator ++ () // prefix		{			++_it;			return *this;		}		Iterator operator ++ (int) // postfix		{			Iterator result(_it);			++_it;			return result;		}		inline const Pair* operator * () const		{			_pair.first  = _it->first;			_pair.second = _it->second.pManifest;			return &_pair;		}		inline const Pair* operator -> () const		{			_pair.first  = _it->first;			_pair.second = _it->second.pManifest;			return &_pair;		}	private:		typename LibraryMap::const_iterator _it;		mutable Pair _pair;	};	ClassLoader()		/// Creates the ClassLoader.	{	}	virtual ~ClassLoader()		/// Destroys the ClassLoader.	{		for (typename LibraryMap::const_iterator it = _map.begin(); it != _map.end(); ++it)		{			delete it->second.pLibrary;			delete it->second.pManifest;		}	}	void loadLibrary(const std::string& path)		/// Loads a library from the given path. Does nothing		/// if the library is already loaded.		/// Throws a LibraryLoadException if the library		/// cannot be loaded or does not have a Manifest.		/// If the library exports a function named "pocoInitializeLibrary",		/// this function is executed.		/// If called multiple times for the same library,		/// the number of calls to unloadLibrary() must be the same		/// for the library to become unloaded.	{		FastMutex::ScopedLock lock(_mutex);		typename LibraryMap::iterator it = _map.find(path);		if (it == _map.end())		{			LibraryInfo li;			li.pLibrary  = new SharedLibrary(path);			li.pManifest = new Manif();			li.refCount  = 1;			try			{				if (li.pLibrary->hasSymbol("pocoInitializeLibrary"))				{					InitializeLibraryFunc initializeLibrary = (InitializeLibraryFunc) li.pLibrary->getSymbol("pocoInitializeLibrary");					initializeLibrary();				}				if (li.pLibrary->hasSymbol("pocoBuildManifest"))				{					BuildManifestFunc buildManifest = (BuildManifestFunc) li.pLibrary->getSymbol("pocoBuildManifest");					if (buildManifest(const_cast<Manif*>(li.pManifest)))						_map[path] = li;					else						throw LibraryLoadException(std::string("Manifest class mismatch in ") + path);				}				else throw LibraryLoadException(std::string("No manifest in ") + path);			}			catch (...)			{				delete li.pLibrary;				delete li.pManifest;				throw;			}		}		else		{			++it->second.refCount;		}	}	void unloadLibrary(const std::string& path)		/// Unloads the given library. 		/// Be extremely cautious when unloading shared libraries.		/// If objects from the library are still referenced somewhere,		/// a total crash is very likely.		/// If the library exports a function named "pocoUninitializeLibrary",		/// this function is executed before it is unloaded.		/// If loadLibrary() has been called multiple times for the same		/// library, the number of calls to unloadLibrary() must be the same		/// for the library to become unloaded.	{		FastMutex::ScopedLock lock(_mutex);		typename LibraryMap::iterator it = _map.find(path);		if (it != _map.end())		{			if (--it->second.refCount == 0)			{				if (it->second.pLibrary->hasSymbol("pocoUninitializeLibrary"))				{					UninitializeLibraryFunc uninitializeLibrary = (UninitializeLibraryFunc) it->second.pLibrary->getSymbol("pocoUninitializeLibrary");					uninitializeLibrary();				}				delete it->second.pManifest;				it->second.pLibrary->unload();				delete it->second.pLibrary;				_map.erase(it);			}		}		else throw NotFoundException(path);	}	const Meta* findClass(const std::string& className) const		/// Returns a pointer to the MetaObject for the given		/// class, or a null pointer if the class is not known.	{		FastMutex::ScopedLock lock(_mutex);		for (typename LibraryMap::const_iterator it = _map.begin(); it != _map.end(); ++it)		{			const Manif* pManif = it->second.pManifest;			typename Manif::Iterator itm = pManif->find(className);			if (itm != pManif->end())				return *itm;		}		return 0;	}		const Meta& classFor(const std::string& className) const		/// Returns a reference to the MetaObject for the given		/// class. Throws a NotFoundException if the class		/// is not known.	{		const Meta* pMeta = findClass(className);		if (pMeta)			return *pMeta;		else			throw NotFoundException(className);	}		Base* create(const std::string& className) const		/// Creates an instance of the given class.		/// Throws a NotFoundException if the class		/// is not known.	{		return classFor(className).create();	}		Base& instance(const std::string& className) const		/// Returns a reference to the sole instance of		/// the given class. The class must be a singleton,		/// otherwise an InvalidAccessException will be thrown.		/// Throws a NotFoundException if the class		/// is not known.	{		return classFor(className).instance();	}		bool canCreate(const std::string& className) const		/// Returns true if create() can create new instances		/// of the class.	{		return classFor(className).canCreate();	}	void destroy(const std::string& className, Base* pObject) const		/// Destroys the object pObject points to.		/// Does nothing if object is not found.	{		classFor(className).destroy(pObject);	}	bool isAutoDelete(const std::string& className, Base* pObject) const		/// Returns true if the object is automatically		/// deleted by its meta object.	{		return classFor(className).isAutoDelete(pObject);	}		const Manif* findManifest(const std::string& path) const		/// Returns a pointer to the Manifest for the given		/// library, or a null pointer if the library has not been loaded.	{		FastMutex::ScopedLock lock(_mutex);		typename LibraryMap::const_iterator it = _map.find(path);		if (it != _map.end())			return it->second.pManifest;		else			return 0;	}		const Manif& manifestFor(const std::string& path) const		/// Returns a reference to the Manifest for the given library		/// Throws a NotFoundException if the library has not been loaded.	{		const Manif* pManif = findManifest(path);		if (pManif)			return *pManif;		else			throw NotFoundException(path);	}	bool isLibraryLoaded(const std::string& path) const		/// Returns true if the library with the given name		/// has already been loaded.	{		return findManifest(path) != 0;	}	Iterator begin() const	{		FastMutex::ScopedLock lock(_mutex);		return Iterator(_map.begin());	}	Iterator end() const	{		FastMutex::ScopedLock lock(_mutex);		return Iterator(_map.end());	}private:	LibraryMap _map;	mutable FastMutex _mutex;};} // namespace Poco#endif // Foundation_ClassLoader_INCLUDED

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -