XNSim/XNMonitorServer/PluginManager.cpp

126 lines
3.2 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "PluginManager.h"
PluginManager &PluginManager::Instance()
{
static PluginManager instance;
return instance;
}
PluginManager::~PluginManager()
{
UnloadCurrentPlugin();
}
void PluginManager::SetGeneratedPluginInfo(const GenPluginInfo &pluginInfo)
{
m_generatedPluginInfo = pluginInfo;
}
bool PluginManager::LoadPluginFromGenerator()
{
if (m_generatedPluginInfo.pluginName.empty()) {
return false;
}
// 构建插件路径 - 安装到outputDirectory上级目录的Plugins下
std::filesystem::path outputPath(m_generatedPluginInfo.outputDirectory);
std::string pluginPath = outputPath.parent_path().string() + "/Plugins/lib"
+ m_generatedPluginInfo.pluginName + "_Monitor.so";
// 卸载当前插件
UnloadCurrentPlugin();
// 加载插件库
m_pluginHandle = dlopen(pluginPath.c_str(), RTLD_LAZY);
if (!m_pluginHandle) {
std::cerr << "Failed to load plugin: " << dlerror() << std::endl;
return false;
}
// 获取插件函数
m_getPluginInfoFunc =
reinterpret_cast<GetPluginInfoFunc>(dlsym(m_pluginHandle, "get_plugin_info"));
m_createMonitorFunc =
reinterpret_cast<CreateMonitorFunc>(dlsym(m_pluginHandle, "create_monitor"));
m_destroyMonitorFunc =
reinterpret_cast<DestroyMonitorFunc>(dlsym(m_pluginHandle, "destroy_monitor"));
m_getSupportedInterfacesFunc = reinterpret_cast<GetSupportedInterfacesFunc>(
dlsym(m_pluginHandle, "get_supported_interfaces"));
m_freeStringArrayFunc =
reinterpret_cast<FreeStringArrayFunc>(dlsym(m_pluginHandle, "free_string_array"));
// 检查函数是否都加载成功
if (!m_getPluginInfoFunc || !m_createMonitorFunc || !m_getSupportedInterfacesFunc) {
std::cerr << "Failed to load plugin functions" << std::endl;
UnloadCurrentPlugin();
return false;
}
// 获取插件信息
m_pluginInfo = m_getPluginInfoFunc();
return true;
}
void PluginManager::UnloadCurrentPlugin()
{
// 先清理监控器缓存这会触发DataMonitorProduct的析构函数
m_monitorCache.clear();
if (m_pluginHandle) {
dlclose(m_pluginHandle);
m_pluginHandle = nullptr;
}
m_pluginInfo = nullptr;
m_getPluginInfoFunc = nullptr;
m_createMonitorFunc = nullptr;
m_destroyMonitorFunc = nullptr;
m_getSupportedInterfacesFunc = nullptr;
m_freeStringArrayFunc = nullptr;
}
DataMonitorBasePtr PluginManager::GetMonitor(const std::string &interfaceName)
{
if (!m_createMonitorFunc) {
return nullptr;
}
// 检查缓存中是否已有实例
auto it = m_monitorCache.find(interfaceName);
if (it != m_monitorCache.end()) {
return it->second;
}
// 创建新实例(不自动初始化)
auto monitor = m_createMonitorFunc(interfaceName.c_str());
// 缓存实例
if (monitor) {
m_monitorCache[interfaceName] = monitor;
}
return monitor;
}
std::vector<std::string> PluginManager::GetSupportedInterfaces()
{
std::vector<std::string> interfaces;
if (!m_getSupportedInterfacesFunc) {
return interfaces;
}
int count = 0;
const char **interfaceNames = m_getSupportedInterfacesFunc(&count);
for (int i = 0; i < count; ++i) {
interfaces.push_back(interfaceNames[i]);
}
return interfaces;
}
bool PluginManager::IsPluginLoaded() const
{
return m_pluginHandle != nullptr && m_createMonitorFunc != nullptr;
}