/** * 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 #include /* 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 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(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(get()); return adapter; } void unload(dlopen_handle handle) noexcept(false) { if (handle == nullptr) { return; } auto stop = reinterpret_cast(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