//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
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;
    }
}
Exemplo n.º 2
0
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~
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;
    }
}