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

📄 plugin_engine.cpp

📁 彩信浏览器
💻 CPP
字号:
// This file is part of Ambulant Player, www.ambulantplayer.org.//// Copyright (C) 2003-2007 Stichting CWI, // Kruislaan 413, 1098 SJ Amsterdam, The Netherlands.//// Ambulant Player 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.//// Ambulant Player 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 Ambulant Player; if not, write to the Free Software// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA#include "ambulant/common/plugin_engine.h"#include "ambulant/lib/logger.h"#include "ambulant/common/preferences.h"#include "ambulant/lib/textptr.h"//#include<dlfcn.h>#include<stdlib.h>#include<string.h>#if defined(WITH_LTDL_PLUGINS) || defined(WITH_WINDOWS_PLUGINS)#define WITH_PLUGINS 1#endif#ifdef WITH_LTDL_PLUGINS#include<dirent.h>#include <ltdl.h>#ifdef AMBULANT_PLATFORM_MACOS#include <CoreFoundation/CoreFoundation.h>#define LIBRARY_PATH_ENVVAR "DYLD_LIBRARY_PATH"#else#define LIBRARY_PATH_ENVVAR "LD_LIBRARY_PATH"#endif // AMBULANT_PLATFORM_MACOS#endif // WITH_LTDL_PLUGINS#ifndef AM_DBG#define AM_DBG if(0)#endif#ifdef _DEBUG#define PLUGIN_PREFIX "libampluginD_"#else#define PLUGIN_PREFIX "libamplugin_"#endifusing namespace ambulant;using namespace common;plugin_engine *ambulant::common::plugin_engine::s_singleton = NULL;plugin_engine *plugin_engine::get_plugin_engine(){    if (s_singleton == NULL)        s_singleton = new plugin_engine;    return s_singleton;}plugin_engine::plugin_engine(){#ifdef WITH_PLUGINS	bool use_plugins = common::preferences::get_preferences()->m_use_plugins;    collect_plugin_directories();#ifdef WITH_LTDL_PLUGINS	lib::logger::get_logger()->trace("plugin_engine: using LTDL plugin loader");	int errors = lt_dlinit();	if (errors) {		lib::logger::get_logger()->trace("LTDL plugin loader: Cannot initialize: %d error(s)", errors);		lib::logger::get_logger()->warn(gettext("Plugin loader encountered problem: plugins disabled"));	    return;	}#endif // WITH_LTDL_PLUGINS#ifdef WITH_WINDOWS_PLUGINS	lib::logger::get_logger()->trace("plugin_engine: using Windows plugin loader");#endif // WITH_WINDOWS_PLUGINS	if (use_plugins) {		int count = 0;		std::vector< std::string >::iterator i;		for (i=m_plugindirs.begin(); i!=m_plugindirs.end(); i++) {			load_plugins(*i);			count++;		}		if (count == 0) {			lib::logger::get_logger()->trace("plugin_engine: no plugin directories configured");		}	} else {		lib::logger::get_logger()->trace("plugin_engine: plugins disabled by user preference");	}#else	lib::logger::get_logger()->trace("plugin_engine: no plugin loader configured");#endif // WITH_PLUGINS}voidplugin_engine::collect_plugin_directories(){#ifdef WITH_PLUGINS	// First dir to search is set per user preferences	std::string& plugin_dir = common::preferences::get_preferences()->m_plugin_dir;	if(plugin_dir != "")		m_plugindirs.push_back(plugin_dir);#ifdef AMBULANT_PLATFORM_MACOS	// On MacOSX add the bundle's plugin dir	CFBundleRef main_bundle = CFBundleGetMainBundle();	if (main_bundle) {		CFURLRef plugin_url = CFBundleCopyBuiltInPlugInsURL(main_bundle);		char plugin_pathname[1024];		if (plugin_url &&				CFURLGetFileSystemRepresentation(plugin_url, true, (UInt8 *)plugin_pathname, sizeof(plugin_pathname))) {			m_plugindirs.push_back(plugin_pathname);		}		if (plugin_url) CFRelease(plugin_url);	}#elif defined(AMBULANT_PLATFORM_UNIX)	// On other unix platforms add the pkglibdir#ifdef AMBULANT_PLUGINDIR	m_plugindirs.push_back(AMBULANT_PLUGINDIR);#else	m_plugindirs.push_back("/usr/local/lib/ambulant");#endif // AMBULANT_PLUGINDIR#elif defined(AMBULANT_PLATFORM_WIN32)	// Add directory containing the main module (either main prog or dll)	std::string main_dir = lib::win32::get_module_dir();	m_plugindirs.push_back(main_dir);#else#error WITH_PLUGINS defined for unknown platform#endif#endif // WITH_PLUGINS}#ifdef WITH_LTDL_PLUGINS#ifdef AMBULANT_PLATFORM_MACOS#define MAYBE_CONST#else#define MAYBE_CONST const#endifstatic int filter(MAYBE_CONST struct dirent* filen){	int len;	len = strlen(filen->d_name);	if (!strncmp(filen->d_name+(len-3),".la",3) ) {		return 1;	} else {		return 0;	}	return 0;}voidplugin_engine::load_plugins(std::string dirname){	lib::logger::get_logger()->trace("plugin_engine: Scanning plugin directory: %s", dirname.c_str());	char filename[1024];	dirent **namelist;	bool ldpath_added = false;	    int nr_of_files = scandir(dirname.c_str(), &namelist, &filter , NULL);    if (nr_of_files < 0) {        lib::logger::get_logger()->trace("Error reading plugin directory: %s: %s", dirname.c_str(), strerror(errno));        return;    } else {        while (nr_of_files--) {            //only normal files, not dots (. and ..)            if (strcmp(namelist[nr_of_files]->d_name, ".")  &&                    strcmp(namelist[nr_of_files]->d_name, "..")) {                char *pluginname = namelist[nr_of_files]->d_name;                                // Check the name is valid                if (strncmp(PLUGIN_PREFIX, pluginname, sizeof(PLUGIN_PREFIX)-1) != 0) {                    lib::logger::get_logger()->trace("plugin_engine: skipping %s", pluginname);                    continue;                }                                // Construct the full pathname                strncpy(filename, dirname.c_str(), sizeof(filename));                strncat(filename, "/", sizeof(filename));                strncat(filename, pluginname, sizeof(filename));								// Add the plugin dir to the search path				if (!ldpath_added) {					setenv(LIBRARY_PATH_ENVVAR, dirname.c_str(), 1);					ldpath_added = true;				}                // Load the plugin                lib::logger::get_logger()->trace("plugin_engine: loading %s", pluginname); 	            lt_dlhandle handle = lt_dlopen(filename);                if (handle) {                    AM_DBG lib::logger::get_logger()->debug("plugin_engine: reading plugin SUCCES [ %s ]",filename);                    AM_DBG lib::logger::get_logger()->debug("Registering  plugin's factory");                    initfuncptr init = (initfuncptr) lt_dlsym(handle,"initialize");                    if (!init) {                        lib::logger::get_logger()->trace("plugin_engine: %s: no initialize routine", filename);                        lib::logger::get_logger()->warn(gettext("Plugin skipped due to errors: %s "), pluginname);                    } else {                        m_initfuncs.push_back(init);                    }					plugin_extra_data *extra = (plugin_extra_data *)lt_dlsym(handle, "plugin_extra_data");					if (extra) {						std::string name = extra->m_plugin_name;						m_extra_data[name] = extra;					}                } else {                    lib::logger::get_logger()->trace("plugin_engine: lt_dlopen(%s) failed: %s",filename, lt_dlerror());					lib::logger::get_logger()->warn(gettext("Plugin skipped due to errors: %s "), pluginname);                }            }            free(namelist[nr_of_files]);        }        free(namelist);    }	lib::logger::get_logger()->trace("plugin_engine: Done with plugin directory: %s", dirname.c_str());	if (ldpath_added)		unsetenv(LIBRARY_PATH_ENVVAR);}#elif WITH_WINDOWS_PLUGINSvoidplugin_engine::load_plugins(std::string dirname){	lib::logger::get_logger()->trace("plugin_engine: Scanning plugin directory: %s", dirname.c_str());	std::string filepattern = 		dirname +//		"\\" +		PLUGIN_PREFIX +		"*.dll";	lib::textptr fp_conv(filepattern.c_str());	WIN32_FIND_DATA dirData;	HANDLE dirHandle = FindFirstFile(fp_conv, &dirData);    if (dirHandle == INVALID_HANDLE_VALUE) {		DWORD err = GetLastError();		if (err != 2) // Don't report "No such file"			lib::logger::get_logger()->error(gettext("Error reading plugin directory: %s: 0x%x"), dirname.c_str(), err);        return;    } else {		do {            // Construct the full pathname			lib::textptr fn_conv(dirData.cFileName);			std::string pathname =				dirname + 				"\\" +				fn_conv.c_str();			lib::textptr pn_conv(pathname.c_str());            // Load the plugin            lib::logger::get_logger()->trace("plugin_engine: loading %s", pathname.c_str()); 	        HMODULE handle = LoadLibrary(pn_conv);            if (handle) {                AM_DBG lib::logger::get_logger()->debug("plugin_engine: reading plugin SUCCES [ %s ]",pathname.c_str());                AM_DBG lib::logger::get_logger()->debug("Registering test plugin's factory");                initfuncptr init = (initfuncptr) GetProcAddress(handle, "initialize");                if (!init) {                    lib::logger::get_logger()->trace("plugin_engine: %s: no initialize routine", pathname.c_str());					lib::logger::get_logger()->warn(gettext("Plugin skipped due to errors: %s "), pathname.c_str());                } else {                    m_initfuncs.push_back(init);                }				plugin_extra_data *extra = (plugin_extra_data *)GetProcAddress(handle, "plugin_extra_data");				if (extra) {					std::string name = extra->m_plugin_name;					m_extra_data[name] = extra;				}	       } else {				DWORD err = GetLastError();				lib::logger::get_logger()->trace("plugin_engine: %s: LoadLibrary returned error 0x%x", pathname.c_str(), err);				lib::logger::get_logger()->warn(gettext("Plugin skipped due to errors: %s"), pathname.c_str());            }		} while(FindNextFile(dirHandle, &dirData));	} 	lib::logger::get_logger()->trace("plugin_engine: Done with plugin directory: %s", dirname.c_str());}#elsevoidplugin_engine::load_plugins(std::string dirname){}#endif // WITH_XXXX_PLUGINSvoidplugin_engine::add_plugins(common::factories* factory, common::gui_player *player){    std::vector< initfuncptr >::iterator i;    for(i=m_initfuncs.begin(); i!=m_initfuncs.end(); i++) {        initfuncptr init;        init = *i;        (init)(AMBULANT_PLUGIN_API_VERSION, factory, player);    }}void *plugin_engine::get_extra_data(std::string name){	if (m_extra_data.count(name) == 0)		return NULL;	return m_extra_data[name]->m_plugin_extra;}

⌨️ 快捷键说明

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