📄 plugin.cpp
字号:
/*************************************************************************** DSemu - The Next Generation ** Plugin core functionality [plugin.cpp] ** Copyright Imran Nazar, 2005; released under the BSD public licence. ***************************************************************************/#include <map>#include <string>#include <fstream>#include <stdio.h>#include "log.h"#include "err.h"#include "plugin.h"#include "config.h"#include "w32compile.h"#ifdef COMPILING_ON_WINDERZ #include <windows.h>#else #include <dlfcn.h>#endif// It's this file that does the grunt work of pulling in a plugin and// initialising it, shutting down, and keeping reference counts.// The plugin mapstd::map<std::string, PLUGINREF> Plugins;//-------------------------------------------------------------------------// Function: Load a plugin (PluginLoad)// Purpose: Open plugin library, retrieve Plugin class, add to list// Parameters: name - FQPN of plugin to load// Returns: Pointer to Plugin class for specified pluginPlugin *PluginLoad(std::string name){ std::string pname, fname; PLUGINREF pinfo; PLUGININFO *ver; // Get the filename for the provided plugin name, from the INI. Config ini; ini.read("plugins.ini"); pname = ini[name]; if(!pname.length()) throw Exception(ERR_PLG_LOAD, "Plugins", std::string("No plugin defined for "+name)); // If we're Win32, load a DLL and get the address of getPlugin through // the WINAPI. #ifdef WIN32 fname = std::string(pname).insert(pname.length(), ".dll"); pinfo.file = LoadLibrary(fname.c_str()); if(!pinfo.file) throw Exception(ERR_PLG_LOAD, "Plugins", std::string("Couldn't load ")+fname);// Logger::log("Plugins") << "Plugin file found: " << fname; GETPLUGIN getp = (GETPLUGIN) GetProcAddress(pinfo.file, "getPlugin"); if(!getp) { FreeLibrary(pinfo.file); throw Exception(ERR_PLG_LOAD, "Plugins", "Unable to locate plugin accessor."); }// Logger::log("Plugins") << "getPlugin address retrieved."; // If not, use the 'dl' library to load a .so file. #else fname = std::string(pname).insert(0, std::string("./")); fname.insert(fname.length(), std::string(".so")); pinfo.file = dlopen(fname.c_str(), RTLD_LAZY); if(!pinfo.file) throw Exception(ERR_PLG_LOAD, "Plugins", std::string("Couldn't load ")+fname+ std::string(": ")+std::string(dlerror()));// Logger::log("Plugins") << "Plugin file found: " << fname; GETPLUGIN getp = (GETPLUGIN) dlsym(pinfo.file, "getPlugin"); if(!getp) { dlclose(pinfo.file); throw Exception(ERR_PLG_LOAD, "Plugins", "Unable to locate plugin accessor."); } // Logger::log("Plugins") << "getPlugin address retrieved."; #endif Plugins[name].name = std::string(pname); Plugins[name].refs = 0; Plugins[name].file = pinfo.file; // Call the plugin's getPlugin, to get the Plugin class. getp(&pinfo.plg, name, PluginRequest, PluginUnrequest); Plugins[name].plg = pinfo.plg; // Get information about the plugin, like its name and who wrote it. ver = pinfo.plg->getinfo(); Logger::log("Plugins") << "Loaded [" << pname << "] " << ver->provider << "'s " << ver->desc; // Start off the active reference count. pinfo.name = std::string(pname); pinfo.refs = 0; // Add the information about this plugin to the Map. typedef std::pair <std::string, PLUGINREF> mapentry_t; //Plugins.insert(mapentry_t(name, pinfo)); return pinfo.plg;}//-------------------------------------------------------------------------// Function: Unload a plugin (PluginUnload)// Purpose: Release the Plugin class and close the library file.// Parameters: name - FQPN of plugin to unload// Returns: Nonevoid PluginUnload(std::string name){ std::string pname; Logger::log("Plugins") << "Unloading " << name; if(Plugins.find(name) == Plugins.end()) throw Exception(ERR_PLG_UNLD, "Plugins", name+" isn't loaded."); pname = Plugins[name].name; if(!Plugins[name].refs) { Plugins[name].plg->release(); #ifdef WIN32 FreeLibrary(Plugins[name].file); #else dlclose(Plugins[name].file); #endif Logger::log("Plugins") << pname << " unloaded."; Plugins.erase(name); } else throw Exception(ERR_PLG_UNLD, "Plugins", name+" still in use.");}//-------------------------------------------------------------------------// Function: Request a Plugin (PluginRequest)// Purpose: Allow a plugin to retrieve a pointer to another// Parameters: name - FQPN of the plugin to load// Returns: Pointer to Plugin objectPlugin *PluginRequest(std::string name){ // If the plugin isn't in the map, load it. if(Plugins.find(name) == Plugins.end()) {// Logger::log("Plugins") << name << " not loaded; loading."; PluginLoad(name); Plugins[name].refs=1; } // Increment the refcount first to resolve circular deps. else Plugins[name].refs++;// printf("%s %08X %d\n", Plugins[name].name.c_str(), Plugins[name].plg, Plugins[name].refs);// Logger::log("Plugins") << "Reference #" << Plugins[name].refs <<// " made to " << name; return Plugins[name].plg;}//-------------------------------------------------------------------------// Function: Un-request a plugin (PluginUnrequest)// Purpose: For a plugin to signify it no longer requires a pointer// to the given plugin// Parameters: name - FQPN of the plugin to unrequest// unload - Boolean, set if plugin unloading is required when// the reference count hits zero// Returns: Nonevoid PluginUnrequest(std::string name, int unload){ if(Plugins.find(name) == Plugins.end()) throw Exception(ERR_PLG_UNRQ, "Plugins", name+" isn't loaded."); if(Plugins[name].refs) {// Logger::log("Plugins") << "Reference #" << Plugins[name].refs <<// " removed from " << name; Plugins[name].refs--; } else throw Exception(ERR_PLG_UNRQ, "Plugins", name+" wasn't requested."); if(!Plugins[name].refs && unload) PluginUnload(name);}/*** EOF: plugin.cpp *****************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -