dmpserverloader.cpp 2.3 KB
/**************************************************************************
* file:              dmpservernativeloader.cpp

* Author:            wanzhongping
* Date:              2020-12-24 16:01:21
* Email:             zhongpingw@chinadci.com
* copyright:         广州城市信息研究所有限公司
***************************************************************************/
#include "dmpserverloader.h"
#include "dmpservermodule.h"
#include <boost/dll/import.hpp>
#include <dlfcn.h>
#include "dmpserverutils.h"

std::shared_ptr<DmpServerModule> DmpServerLoader::loadModule(const std::string &location)
{
    std::shared_ptr<DmpServerModule> sp_module = findModule(location);
    if (sp_module)
    {
        return sp_module;
    }

    boost::dll::fs::error_code error;
    std::shared_ptr<boost::dll::shared_library> lib = std::make_shared<boost::dll::shared_library>(location, error);
    if (error)
    {
        return nullptr;
    }
    if (lib->has("server_module"))
    {
        sp_module = boost::move(lib)->get_alias<std::shared_ptr<DmpServerModule>()>("server_module")();
        if (sp_module)
        {
            //保存lib的引用,否则sp_module会被释放掉
            sp_module->set_lib(boost::move(lib));
            modules_[location] = sp_module;
            return sp_module;
        }
    }
    return nullptr;
}

void DmpServerLoader::loadModules(const boost::filesystem::path &module_path,
                                         DmpServerRegistry &registry)
{
    std::vector<boost::filesystem::path> locations;
    DmpServerUtils::GetLibraryPaths(module_path, locations);

    std::vector<boost::filesystem::path>::iterator iter;
    for (iter = locations.begin(); iter != locations.end(); iter++)
    {
        std::shared_ptr<DmpServerModule> sp_module = loadModule(iter->string());
        if (sp_module)
        {
            sp_module->registerSelf(registry);
        }
    }
}

std::shared_ptr<DmpServerModule> DmpServerLoader::findModule(const std::string &location)
{
    ModuleMap::iterator item = modules_.find(location);
    if (item != modules_.end())
    {
        return item->second;
    }
    return nullptr;
}

void DmpServerLoader::unloadModules()
{
    modules_.clear();
}