Files
qt5-legatus-legacy/Lts/Proxies/TrainingAreaBase/Plugins/UAS/TmsIfAdapter/module_loader.h
T
2026-08-13 18:33:10 +02:00

79 lines
1.9 KiB
C++
Executable File

/**
* Loads and manages the libTmsIfAdapter module
* $Id$
* $HeadURL$
* $Author$
*
* Created by Mike Wille, ESZS, 2025-04-17
*/
#pragma once
#include "tms_if_adapter.h"
#include <stdexcept>
#include <string>
/* there's a massive problem with symbol collision between RTI DDS & Cyclone DDS (namely dds::core::Time::invalid())
* so we need the linux specific RTLD_DEEPBIND to force the use of the Cyclone DDS symbols inside the library */
#include <dlfcn.h>
namespace UAS
{
namespace ModuleLoader
{
using dlopen_handle = void *;
dlopen_handle load(std::string libPath) noexcept(false)
{
dlopen_handle handle = dlopen((libPath + "/libTmsIfAdapter.so").c_str(), RTLD_NOW | RTLD_LOCAL | RTLD_DEEPBIND);
if (handle == nullptr)
{
throw std::runtime_error((std::string("tms_if.h => ModuleLoader::load: unable to load libTmsIfAdapter.so: ") + dlerror()).c_str());
}
return handle;
}
TmsIfAdapter &get(dlopen_handle handle) noexcept(false)
{
auto get = reinterpret_cast<void *(*)()>(dlsym(handle, "get"));
if (get == nullptr)
{
throw std::runtime_error((std::string("tms_if.h => ModuleLoader::get: function symbol 'get' does not exist in libTmsIfAdapter.so: ") + dlerror()).c_str());
}
UAS::TmsIfAdapter &adapter = *reinterpret_cast<UAS::TmsIfAdapter *>(get());
return adapter;
}
void unload(dlopen_handle handle) noexcept(false)
{
if (handle == nullptr)
{
return;
}
auto stop = reinterpret_cast<void *(*)()>(dlsym(handle, "stop"));
if (stop == nullptr)
{
throw std::runtime_error((std::string("tms_if.h => ModuleLoader::unload: function symbol 'stop' does not exist in libTmsIfAdapter.so: ") + dlerror()).c_str());
}
stop();
const int ret = dlclose(handle);
if (ret != 0)
{
throw std::runtime_error((std::string("tms_if.h => ModuleLoader::unload: dlclose failed - ret != 0 (was "+std::to_string(ret)+"): ") + dlerror()).c_str());
}
}
} // ModuleLoader
} // namespace UAS