【发布时间】:2015-10-08 22:48:10
【问题描述】:
我确实环顾了 SO 和其他地方,但找不到这个非常标准的问题的令人满意的答案。我对 linux 和标准合规性特别感兴趣。我遇到了以下方法
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));
}
这种做事方式是否正确且符合标准?特别是,我可以从具有extern "C" 链接的函数中返回std::unique_ptr<> 吗?这样的函数可以采用 const 引用参数吗?我是否必须将create_ptr 声明为extern "C"(在文件plugin.cc 中)?我可以避免 extern "C" 并直接获取 C++ 符号(this article 讨论这个是针对 windows,而不是 linux,并且是特定于编译器的)?
【问题讨论】:
-
它最终将获得特定的编译器/运行时环境,因为 c++ 标准不依赖于任何概念,如静态或动态链接。
-
据我所知,插件没有标准。插件也没有合规性。这都是特定于平台和操作系统的。
标签: c++ linux plugins extern unique-ptr