Я смотрел вокруг SO и в другом месте, но не смог найти удовлетворительного ответа на этот довольно стандартный вопрос. Меня особенно интересует Linux и стандартное соответствие. Я наткнулся на следующий подходКак реализовать плагин C++ стандартным образом?
file plugin.h
часть библиотеки
#include <memory>
#include <string>
/// defines an interface to be implemented by a plugin
struct PluginBase
{
virtual~PluginBase() {}
virtual double calc(double) const = 0;
};
/// loads a plugin
/// \param[in] file shared object file to load and find plugin in
/// \param[in] strg data for initialising the plugin
std::unique_ptr<PluginBase> load_plugin(std::string const&file, std::string const&strg);
extern "C" {
/// to be implemented with plugin
/// \param[in] strg data for initialising the plugin
std::unique_ptr<PluginBase> create_plugin(std::string const&strg);
}
file plugin.cc
часть библиотеки
#include "plugin.h"
#include <cassert>
extern "C" {
#include <dlfcn.h> // dlopen() dlsym()
std::unique_ptr<PluginBase>(*create_ptr)(std::string const&);
}
std::unique_ptr<PluginBase> load_plugin(std::string const&file,
std::string const&strg)
{
auto handle = dlopen(file.c_str(),RTLD_LAZY|RTLD_GLOBAL);
assert(handle); // in lieu of proper error handling
auto func_ptr = dlsym(handle,"create_plugin");
assert(func_ptr); // ditto
return reinterpret_cast<create_ptr>(func_ptr)(strg);
}
file some_plugin.cc
не является частью библиотеки
#include "plugin.h"
struct PluginImpl : PluginBase
{
PluginImpl(std::string const&);
double calc(double) const override;
};
/// has extern "C" linkage
std::unique_ptr<PluginBase> create_plugin(std::string const&strg)
{
return std::unique_ptr<PluginBase>(new PluginImpl(strg));
}
Является ли этот путь делать что-то правильно и стоять ard совместимый? В частности, могу ли я вернуть std::unique_ptr<>
из функции с привязкой extern "C"
? и может ли такая функция принимать аргумент const? Должен ли я объявлять create_ptr
как extern "C"
(в файле plugin.cc
)? Могу ли я избежать extern "C"
и напрямую получать символы C++ (this article обсуждает это для Windows, а не linux и является специфичным для компилятора)?
Это наконец-то, чтобы получить компилятор/среда выполнения конкретных, потому что стандарты C++ не полагаются на такие понятия, как статическая или динамическая связь. –
Насколько мне известно, стандартов для плагинов нет. Также нет совместимости с плагинами. Это вся платформа и ОС. –