dmpservicenativeloader.cpp 2.5 KB
/*
 * @Author: your name
 * @Date: 2021-04-26 11:49:54
 * @LastEditTime: 2021-04-26 11:53:35
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: /dmapserver/src/server/dmpservicenativeloader.cpp
 */
/**************************************************************************
* file:              dmpservicenativeloader.cpp

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

std::shared_ptr<DmpServiceModule> DmpServiceNativeLoader::LoadNativeModule(const std::string &location)
{
    std::shared_ptr<DmpServiceModule> 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("service_module"))
    {
        sp_module = boost::move(lib)->get_alias<std::shared_ptr<DmpServiceModule>()>("service_module")();
        if (sp_module)
        {
            //保存lib的引用,否则sp_module会被释放掉
            sp_module->set_lib(boost::move(lib));
            modules_[location] = sp_module;
            return sp_module;
        }
    }
    return nullptr;
}

void DmpServiceNativeLoader::LoadModules(const boost::filesystem::path &module_path,
                                         DmpServiceRegistry &registrar)
{
    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<DmpServiceModule> sp_module = LoadNativeModule(iter->string());
        if (sp_module)
        {
            sp_module->RegisterSelf(registrar);
        }
    }
}

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

void DmpServiceNativeLoader::UnloadModules()
{
    modules_.clear();
}