//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ I_ModuleService::module_ptr_type ModuleService::load(const std::string& _moduleName) { // Get the logger stream Zen::Utility::log_stream& logStream( I_PluginManager::getSingleton().getApplication()->getLogStream() ); // Guard this method boost::shared_ptr<Threading::CriticalSection> pGuard( new Threading::CriticalSection(m_pModuleGuard) ); module_name_index_type::iterator iter = m_moduleIndex.find(_moduleName); if(iter != m_moduleIndex.end()) { // Increment the reference count m_modules[iter->second]->incrementReferences(); // Return the return iter->second; } module_info_ptr_type pModuleInfo(new ModuleInfo); I_ModuleManager* pModuleManager = &I_ModuleManager::getSingleton(); boost::filesystem::path modulePath; if(!pModuleManager->findPath(_moduleName, modulePath)) { logStream << "DEBUG: Module " << _moduleName << " not found in defined module search paths." << std::endl; // TODO: Throw an exception with the error return NULL; } pModuleInfo->setName(_moduleName); #ifdef _WIN32 I_ModuleInfo::module_handle_type hModule = LoadLibraryA(modulePath.string().c_str()); #else logStream << "DEBUG: dlopen " << modulePath.string().c_str() << std::endl; I_ModuleInfo::module_handle_type hModule = dlopen(modulePath.string().c_str(), RTLD_NOW | RTLD_GLOBAL); #endif // _WIN32 if (hModule == NULL) { int err = Zen::Utility::GetLastError(); logStream << "DEBUG: Error loading module " << modulePath.string() #ifndef _WIN32 << dlerror() #else << (err == 14001 ? "probably the module has dependencies not on the path. Use depends.exe to figure it out." : "") #endif << std::endl; // TODO: Throw an exception with the error return NULL; #if 0 std::stringstream errorStream; errorStream << "Unable to find plugin module: " << moduleName.str(); pPluginInfo->setError(errorStream.str()); #endif } pModuleInfo->setHandle(hModule); // Get the "getModule" procedure #if defined _WIN32 FARPROC proc = GetProcAddress(hModule, "getModule"); #else void* proc = dlsym(hModule, "getModule"); #endif // Check to make sure the procedure exists if (proc) { // Convert the procedure type to the assumed type #ifdef _WIN32 I_Module::proc_ptr_type pRealProc = (I_Module::proc_ptr_type)proc; #else I_Module::QUERY_MODULE_FUNCTION_PTR pRealProc = reinterpret_cast<I_Module::QUERY_MODULE_FUNCTION_PTR>(proc); #endif // Execute the procedure to get the I_Module for this module. module_ptr_type pModule = &(pRealProc()); // Set the reference count to 1 pModuleInfo->incrementReferences(); // Put it in the index m_moduleIndex[_moduleName] = pModule; // Put it in the cache m_modules[pModule] = pModuleInfo; // And return it. return pModule; } else { logStream << "DEBUG: Error getting procedure address in module " << modulePath.string() << " Error " << Zen::Utility::GetLastError() << std::endl; // Not found, so return NULL return NULL; } }
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ I_ModuleService::pModule_type ModuleService::load(const std::string& _moduleName) { boost::lock_guard<boost::mutex> guard(m_moduleMutex); ModuleNameIdx_type::iterator iter = m_moduleIdx.find(_moduleName); if(iter != m_moduleIdx.end()) { // Increment the reference count m_modules[iter->second]->incrementReferences(); // Return the return iter->second; } pModuleInfo_type pModuleInfo(new ModuleInfo); I_ModuleManager* pModuleManager = &I_ModuleManager::getSingleton(); boost::filesystem::path modulePath; if(!pModuleManager->findPath(_moduleName, modulePath)) { std::stringstream stream; stream << "Module " << _moduleName << " not found in defined module search paths."; BOOST_LOG_TRIVIAL(error) << stream.str(); throw std::exception(stream.str().c_str()); } pModuleInfo->setName(_moduleName); #ifdef _WIN32 I_ModuleInfo::ModuleHandle_type hModule = LoadLibraryA(modulePath.string().c_str()); #else BOOST_LOG_TRIVIAL(info) << "dlopen " << modulePath.string().c_str(); I_ModuleInfo::ModuleHandle_type hModule = dlopen(modulePath.string().c_str(), RTLD_NOW | RTLD_GLOBAL); #endif // _WIN32 if (hModule == NULL) { std::stringstream stream; stream << "Error loading module " << modulePath.string() #ifndef _WIN32 << dlerror() #else << ": The module is probably missing dependencies not on the path. Use depends.exe to figure it out." #endif ; BOOST_LOG_TRIVIAL(error) << stream.str(); throw std::exception(stream.str().c_str()); } pModuleInfo->setHandle(hModule); // Get the "getModule" procedure #if defined _WIN32 FARPROC proc = GetProcAddress(hModule, "getModule"); #else void* proc = dlsym(hModule, "getModule"); #endif // Check to make sure the procedure exists if (proc) { // Convert the procedure type to the assumed type #ifdef _WIN32 I_Module::proc_ptr_type pRealProc = (I_Module::proc_ptr_type)proc; #else I_Module::QUERY_MODULE_FUNCTION_PTR pRealProc = reinterpret_cast<I_Module::QUERY_MODULE_FUNCTION_PTR>(proc); #endif // Execute the procedure to get the I_Module for this module. pModule_type pModule = &(pRealProc()); // Set the reference count to 1 pModuleInfo->incrementReferences(); // Put it in the index m_moduleIdx[_moduleName] = pModule; // Put it in the cache m_modules[pModule] = pModuleInfo; // And return it. return pModule; } else { BOOST_LOG_TRIVIAL(error) << "Error getting procedure address in module " << modulePath.string(); // Not found, so return NULL return NULL; } }