r3375 - in trunk/libmutil: include/libmutil source

erik at minisip.org erik at minisip.org
Mon Aug 20 16:16:09 CEST 2007


Author: erik
Date: 2007-08-20 16:16:09 +0200 (Mon, 20 Aug 2007)
New Revision: 3375

Added:
   trunk/libmutil/source/LibraryWin32.cxx
   trunk/libmutil/source/MPluginWin32.cxx
Modified:
   trunk/libmutil/include/libmutil/Library.h
   trunk/libmutil/include/libmutil/MPlugin.h
Log:

 * Add Library and MPlugin implementations that can 
   be used if compiling with Microsoft Visual Studio

Modified: trunk/libmutil/include/libmutil/Library.h
===================================================================
--- trunk/libmutil/include/libmutil/Library.h	2007-08-20 14:10:52 UTC (rev 3374)
+++ trunk/libmutil/include/libmutil/Library.h	2007-08-20 14:16:09 UTC (rev 3375)
@@ -59,6 +59,7 @@
 
 	/**
 	 * @returns the file name from which the library was loaded.
+	 *	    On Win32 this is the same as the argument given to open( ).
 	 */
 	const std::string &getPath();
 

Modified: trunk/libmutil/include/libmutil/MPlugin.h
===================================================================
--- trunk/libmutil/include/libmutil/MPlugin.h	2007-08-20 14:10:52 UTC (rev 3374)
+++ trunk/libmutil/include/libmutil/MPlugin.h	2007-08-20 14:16:09 UTC (rev 3375)
@@ -153,6 +153,9 @@
 		/**
 		 * Set directory search path used by loadFromLibrary,
 		 * and loadFromFile.
+		 * Win32: On pre-WXPSP1 this method changes
+		 *        the applications current working directory.
+		 *        
 		 **/
 		bool setSearchPath( const std::string &searchPath );
 

Added: trunk/libmutil/source/LibraryWin32.cxx
===================================================================
--- trunk/libmutil/source/LibraryWin32.cxx	                        (rev 0)
+++ trunk/libmutil/source/LibraryWin32.cxx	2007-08-20 14:16:09 UTC (rev 3375)
@@ -0,0 +1,72 @@
+/*
+  Copyright (C) 2004-2006 the Minisip Team
+  
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+/*
+ * Copyright (C) 2004-2006
+ *
+ * Authors: Erik Eliasson <eliasson at it.kth.se>
+ *          Johan Bilien <jobi at via.ecp.fr>
+ *          Mikael Magnusson <mikma at users.sourceforge.net>
+*/
+
+#include<config.h>
+#include<libmutil/Library.h>
+#include<libmutil/massert.h>
+
+#include<windows.h>
+
+#include<iostream>
+
+
+using namespace std;
+
+int Library::refCount=0;
+
+Library::Library(const string &path_):path(path_){
+	refCount++;
+	handle = new HMODULE;
+	*((HMODULE*)handle) = LoadLibrary( path.c_str() );
+
+}
+
+Library::~Library(){
+	massert(handle);
+	BOOL ok = FreeLibrary( *((HMODULE*)handle) );
+	massert(ok);
+	handle = NULL;
+	refCount--;
+}
+
+void *Library::getFunctionPtr(string name){
+	return (void*)GetProcAddress( *((HMODULE*)handle), name.c_str() );
+}
+
+
+MRef<Library *> Library::open(const string &path){
+	MRef<Library *> ret = new Library(path);
+	if(ret->handle){
+		ret->path = path;
+		return ret;
+	}
+	ret = NULL;
+	return ret;
+}
+
+const string &Library::getPath(){
+	return path;
+}

Added: trunk/libmutil/source/MPluginWin32.cxx
===================================================================
--- trunk/libmutil/source/MPluginWin32.cxx	                        (rev 0)
+++ trunk/libmutil/source/MPluginWin32.cxx	2007-08-20 14:16:09 UTC (rev 3375)
@@ -0,0 +1,318 @@
+/*
+  Copyright (C) 2004-2006 the Minisip Team
+  
+  This library is free software; you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public
+  License as published by the Free Software Foundation; either
+  version 2.1 of the License, or (at your option) any later version.
+
+  This library is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this library; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+/*
+ * Copyright (C) 2004-2006
+ *
+ * Authors: Erik Eliasson <eliasson at it.kth.se>
+ *          Johan Bilien <jobi at via.ecp.fr>
+ *          Mikael Magnusson <mikma at users.sourceforge.net>
+*/
+
+
+#include<config.h>
+
+#include<libmutil/dbg.h>
+#include<libmutil/FileSystemUtils.h>
+#include<libmutil/MPlugin.h>
+#include<libmutil/Library.h>
+#include<windows.h>
+using namespace std;
+
+MRef<MPluginManager*> MPluginManager::instance;
+
+MPlugin::MPlugin(MRef<Library*> lib): library( lib ){
+}
+
+MPlugin::MPlugin(): library( NULL ){
+}
+
+MPlugin::~MPlugin(){
+}
+
+string MPlugin::getMemObjectType() const{
+	return "MPlugin";
+}
+
+MPluginManager::MPluginManager(){
+	libraries.clear();
+}
+
+MPluginManager::~MPluginManager(){
+	libraries.clear();
+	registries.clear();
+}
+
+MRef<MPluginManager*> MPluginManager::getInstance(){
+	if( !instance ){
+		instance = new MPluginManager();
+	}
+
+	return instance;
+}
+
+list<string> * MPluginManager::getListFromLibrary( MRef<Library *> lib ){
+	MPlugin::lister listerFunction;
+
+	listerFunction = (MPlugin::lister)lib->getFunctionPtr( "listPlugins" );
+
+	if( listerFunction ){
+		return listerFunction( lib );
+	}
+
+	return NULL;
+}
+
+int32_t MPluginManager::loadFromFile( const std::string &filename ){
+	int32_t nPlugins = 0;
+	list<string> * entryPoints;
+	MRef<Library *> lib;
+	list< MRef<Library *> >::iterator iLib;
+
+	lib = Library::open( filename );
+
+	if( !lib ){
+		mdbg << "MPluginManager: Can't load " << filename << endl;
+		// Continue;
+		return -1;
+	}
+
+	for( iLib = libraries.begin(); iLib != libraries.end(); iLib++ ){
+		MRef<Library *> cur = *iLib;
+
+		if( cur->getPath() == lib->getPath() ){
+			mdbg << "MPluginManager: Already loaded " << filename << endl;
+			return -1;
+		}
+	}
+
+	entryPoints = getListFromLibrary( lib );
+
+	if( entryPoints ){
+		list<string>::iterator iEP;
+		for( iEP = entryPoints->begin(); 
+		     iEP!= entryPoints->end();
+		     iEP ++ ){
+			MRef<MPlugin *> p;
+
+			p = loadFromLibrary( lib, *iEP );
+			if( p ){
+				if( registerPlugin( p ) ){
+					nPlugins ++;
+				}
+			}
+			else {
+				merr << "MPluginManager: No plugin for ep: " << *iEP << endl;
+			}
+		}
+	}
+	else{
+		merr << "MPluginManager: No entrypoints in " << filename << endl;
+	}
+
+	if( nPlugins > 0 ){
+		libraries.push_back( lib );
+	}
+	else {
+		mdbg << "MPluginManager: No plugins loaded from " << lib->getPath() << endl;
+	}
+	return nPlugins;
+}
+
+#if 0
+struct ltdl_info {
+		ltdl_info() : manager(NULL),nTotalPlugins(0){}
+		~ltdl_info(){manager=NULL;}
+
+		MRef<MPluginManager *> manager;
+		int32_t nTotalPlugins;
+};
+
+static int ltdl_callback(const char *filename, lt_ptr data){
+	ltdl_info *info = (ltdl_info*)data;
+	int32_t nPlugins;
+
+	nPlugins = info->manager->loadFromFile( filename );
+
+	if( nPlugins > 0 ){
+		info->nTotalPlugins += nPlugins;
+	}
+
+	// Continue;
+	return 0;
+}
+
+#endif
+
+int32_t MPluginManager::loadFromDirectory( const string &path ){
+
+	list<string> files = FileSystemUtils::directoryContents(path,false);
+	list<string>::iterator i=files.begin();
+	int nLoaded=0;
+	for ( ; i!=files.end(); i++){
+		int n = this->loadFromDirectory( *i );
+		if  (n>0)
+			nLoaded+=n;
+	}
+	return nLoaded;
+#if 0
+	ltdl_info info;
+	info.manager = this;
+
+	int res = lt_dlforeachfile(path.c_str(), ltdl_callback, &info);
+	if( res < 0 ){
+		merr << lt_dlerror() << endl;
+	}
+	return info.nTotalPlugins;
+#endif
+}
+
+MRef<MPlugin *> MPluginManager::loadFromLibrary( const string &file, 
+						 const string &entryPoint ){
+	MRef<Library *> lib = NULL;
+	list< MRef<Library *> >::iterator iLib;
+	MRef<MPlugin *> p;
+	bool newLib = false;
+
+	for( iLib = libraries.begin(); iLib != libraries.end(); iLib ++ ){
+		if( (*iLib)->getPath() == file ){
+			lib = *iLib;
+		}
+	}
+
+	/* This library hasn't been opened yet */
+	if( !lib ){
+		lib = Library::open( file );
+		if( lib ){
+			newLib = true;
+		}
+	}
+
+	p =  loadFromLibrary( lib, entryPoint );
+
+	if( p && newLib ){
+		libraries.push_back( lib );
+	}
+
+	return p;
+}
+
+
+MRef<MPlugin *> MPluginManager::loadFromLibrary( MRef<Library *> lib, 
+					  const string &entryPoint ){
+	MPlugin::creator creatorFunction;
+
+	if( !lib ){
+		/* This library doen't exist or couldn't be opened */
+		return NULL;
+	}
+
+	creatorFunction = (MPlugin::creator)(lib->Library::getFunctionPtr(
+				entryPoint ));
+
+	if( creatorFunction ){
+		MRef<MPlugin *> pp = creatorFunction( lib );
+		
+		if( !pp.isNull() ){
+			mdbg << "MPluginManager: loaded " << pp->getName() << "(" << pp->getDescription() << ")" << endl;
+			return pp;
+		}
+	}
+
+	return NULL;
+}
+
+bool MPluginManager::registerPlugin( MRef<MPlugin *> p ){
+	std::list< MPluginRegistry * >::iterator iReg;
+
+
+	for( iReg = registries.begin(); iReg != registries.end(); iReg ++ ){
+		if( (*iReg)->getPluginType() == p->getPluginType() ){
+			(*iReg)->registerPlugin( p );
+			return true;
+		}
+	}
+
+	merr << "MPluginManager: Can't find registry for " << p->getPluginType() << endl;
+	return false;
+}
+
+void MPluginManager::addRegistry( MPluginRegistry * registry ){
+	registries.push_back( registry );
+}
+
+void MPluginManager::removeRegistry( MPluginRegistry * registry ){
+	registries.remove( registry );
+}
+
+bool MPluginManager::setSearchPath( const std::string &searchPath ){
+	mdbg << "MPluginManager: setSearchPath " << searchPath << endl;
+
+	/*
+	We want to use SetDllDirectory, but it is only available
+	on WXP+SP1/Vista. As a fallback we change the current
+	directory.
+	*/
+	HMODULE k32 = GetModuleHandle("kernel32.dll");
+	if (k32){
+		typedef BOOL (CALLBACK* SETDLLDIR_FUNC_TYPE)(LPCTSTR);
+		SETDLLDIR_FUNC_TYPE setDllDir = (SETDLLDIR_FUNC_TYPE)GetProcAddress(k32,"SetDllDirectory");
+		if (setDllDir){
+			return setDllDir( searchPath.c_str() ) != 0;
+		}
+	}
+
+	return SetCurrentDirectory(searchPath.c_str())!=0;
+}
+
+void MPluginRegistry::registerPlugin( MRef<MPlugin *> p ){
+	plugins.push_back( p );
+}
+
+MPluginRegistry::MPluginRegistry(){
+	manager = MPluginManager::getInstance();
+	manager->addRegistry( this );
+}
+
+MPluginRegistry::~MPluginRegistry(){
+	plugins.clear();
+	manager->removeRegistry( this );
+}
+
+MRef<MPlugin*> MPluginRegistry::findPlugin( std::string name ){
+	list< MRef<MPlugin *> >::iterator iter;
+	list< MRef<MPlugin *> >::iterator last = plugins.end();
+
+	for( iter = plugins.begin(); iter != last; iter++ ){
+		MRef<MPlugin *> plugin = *iter;
+
+		if( plugin->getName() == name ){
+			return plugin;
+		}
+	}
+
+	return NULL;
+}
+
+MPluginRegistry::const_iterator MPluginRegistry::begin() const{
+	return plugins.begin();
+}
+
+MPluginRegistry::const_iterator MPluginRegistry::end() const{
+	return plugins.end();
+}



More information about the Minisip-devel mailing list