--- /dev/null
+#ifndef __PLUGIN_PROXY_H__
+#define __PLUGIN_PROXY_H__
+
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "shared_library.h"
+#include "PluginException.h"
+#include "PluginInstance.h"
+
+namespace nncc
+{
+namespace contrib
+{
+namespace module
+{
+namespace plugin
+{
+
+class PluginProxy
+{
+public:
+ PluginProxy() = delete;
+ static std::shared_ptr<PluginProxy> create(const std::string &pluginPath);
+ virtual ~PluginProxy();
+
+ const std::string &getPluginPath() const;
+ const std::string &getPluginName() const;
+
+ std::shared_ptr<contrib::plugin::AbstractPluginInstance> getPluginInstance();
+
+public:
+ static const std::string getInstanceFuncName;
+
+private:
+ explicit PluginProxy(const std::string &pluginPath);
+
+ void init() noexcept(false);
+ void *getFuncAddr(const std::string &func_name) noexcept(false);
+ friend std::ostream &operator<<(std::ostream &st, const PluginProxy &pl);
+
+private:
+ typedef std::shared_ptr<contrib::plugin::AbstractPluginInstance> (*get_instance_t)();
+
+ std::shared_ptr<contrib::plugin::AbstractPluginInstance> _pluginInstance;
+ std::shared_ptr<SharedLibrary> _lib;
+ get_instance_t _getInstance;
+ std::string _pluginName;
+};
+
+} // namespace plugin
+} // namespace module
+} // namespace contrib
+} // namespace nncc
+
+#endif /* __PLUGIN_PROXY_H__ */
--- /dev/null
+#include <string>
+#include <memory>
+#include "module/plugin/PluginProxy.h"
+
+namespace nncc
+{
+namespace contrib
+{
+namespace module
+{
+namespace plugin
+{
+
+const std::string PluginProxy::getInstanceFuncName = "get_instance";
+
+void *PluginProxy::getFuncAddr(const std::string &func_name) {
+ void *fp;
+ fp = _lib->findFunc(func_name);
+
+ if (fp == nullptr)
+ throw PluginException(std::string("function not found: <") + func_name + ">");
+ return fp;
+}
+
+PluginProxy::PluginProxy(const std::string &pluginPath) : _getInstance(nullptr), _lib(nullptr), _pluginInstance(nullptr) {
+ _lib = std::make_shared<SharedLibrary>(pluginPath);
+
+ auto i = pluginPath.find_last_of('/');
+ if (i != std::string::npos)
+ _pluginName = pluginPath.substr(i + 1);
+ else
+ _pluginName = pluginPath;
+}
+
+void PluginProxy::init() noexcept(false) {
+ // Fill instance
+ _getInstance = (PluginProxy::get_instance_t) getFuncAddr(getInstanceFuncName);
+ _pluginInstance = _getInstance();
+
+ if (_pluginInstance == nullptr)
+ throw PluginException("bad plugin instance");
+}
+
+std::shared_ptr<PluginProxy> PluginProxy::create(const std::string &pluginPath) {
+ std::shared_ptr<PluginProxy> pl = nullptr;
+ try {
+ pl = std::shared_ptr<PluginProxy>(new PluginProxy(pluginPath));
+ pl->init();
+ return pl;
+ }
+ catch (PluginException &e) {
+ throw PluginException(e, "cannot create plugin");
+ }
+}
+
+PluginProxy::~PluginProxy() {}
+
+std::ostream &operator<<(std::ostream &st, const PluginProxy &pl) {
+ st << *(pl._lib);
+ return st;
+}
+
+const std::string &PluginProxy::getPluginPath() const { return _lib->getPath(); }
+
+const std::string &PluginProxy::getPluginName() const { return _pluginName; }
+
+std::shared_ptr<contrib::plugin::AbstractPluginInstance> PluginProxy::getPluginInstance() {
+ if (_pluginInstance == nullptr)
+ throw PluginException(std::string("bad plugin instance <") + getPluginPath() + ">");
+ return _pluginInstance;
+}
+
+} // namespace plugins
+} // namespace module
+} // namespace contrib
+} // namespace nncc