返回

动态库加载的 C++ 依赖注入

发布时间:2022-08-17 11:41:17 346
# golang

我无法将 C++ 依赖注入库“ boost::di ”与另一个 boost 库一起用于动态加载名为“ Boost.dll ”的库。

我将问题分为两部分 - 首先,测试动态加载,其次,将抽象类绑定到实现(动态加载)。

我能够成功地动态加载库。但是当我尝试使用依赖注入绑定时,它会报告类模板是预期的但未收到的不匹配。

我在这个 repo 中有一个非常基本的示例代码: https ://bitbucket.org/kobe_la/boost-plugins-prework/src/master/

我真的会使用一些帮助来确定动态加载库的绑定过程。(请参阅底部的确切错误)

  • ioperation.hpp

     #include 
    
     class ioperation {
    
     public:
         virtual std::string name() const = 0;
         virtual float calculate(float x, float y) = 0;
    
         virtual ~ioperation() {}
     };
    
  • 文件sum.cpp

     #include <boost/config.hpp>
     #include <boost/dll/alias.hpp>
     #include <boost/dll/import.hpp>
     #include "ioperation.hpp"
     #include 
    
     namespace sum_namespace {
    
     class sum: public ioperation {
     public:
         sum() {
             std::cout << "[sum_constructor]" << std::endl;
         }
    
         std::string name() const {
             return "sum";
         }
    
         float calculate(float x, float y) {
             return x + y;
         }
    
         ~sum() {
             std::cout << "[~sum_destructor]" << std::endl;
         }
    
    
            // Factory method
             static boost::shared_ptr create_sum() {
                     return boost::shared_ptr(
                             new sum()
                     );
             }
         };
     }
    
     BOOST_DLL_ALIAS(
         sum_namespace::sum::create_sum, // <-- this function is exported with...
         create_sum                                       // <-- ...this alias name
     )
    
  • 文件dot_product.cpp

     #include <boost/config.hpp>
     #include <boost/dll/alias.hpp>
     #include <boost/dll/import.hpp>
     #include 
     #include "ioperation.hpp"
    
     namespace dot_product_namespace {
    
     class dot_product: public ioperation {
    
             boost::shared_ptr sum_ptr;
     public:
             dot_product(boost::shared_ptr &arg) {
                     sum_ptr = arg;
                     std::cout << "[dot_product_constructor]" << std::endl;
             }
    
             std::string name() const {
                     return "dot_product";
             }
    
             float calculate(float a1, float a2) {
                     //dot product given vector with itself
                     //formula: a.b = a1*b1 + a2*b2
                     return sum_ptr->calculate(a1*a1, a2*a2);
             }
    
             // Factory method
             static boost::shared_ptr create_dot_product(boost::shared_ptr sum_ptr) {
                     return boost::shared_ptr(
                             new dot_product(sum_ptr)
                     );
             }
    
             ~dot_product() {
                     std::cout << "[~dot_product_destructor]" << std::endl;
             }
         };
     };
    
     BOOST_DLL_ALIAS(
         dot_product_namespace::dot_product::create_dot_product, // <-- this function is exported with...
         create_dot_product                               // <-- ...this alias name
     )
    
  • 文件application_di.cpp

     #include "boost/shared_ptr.hpp"
     #include <boost/dll/import.hpp>
     #include "boost/function.hpp"
     #include <boost/di.hpp>
     #include "ioperation.hpp"
     #include 
    
     namespace di = boost::di;
     namespace dll = boost::dll;
    
    
     class app {
      private:
         boost::shared_ptr ptr_;
      public:
         app(boost::shared_ptr ptr)
          : ptr_(ptr)
         {
                std::cout<<"name: " << ptr_->name()<<std::endl;
         }
    
     };
    
    
     int main(int argc, char* argv[]) {
    
         //setting up paths to library(.so) files
             boost::filesystem::path shared_library_path(".");    // argv[1] contains path to directory with our plugin library
             boost::filesystem::path child_library_path = shared_library_path/"dot_product";
             boost::filesystem::path parent_library_path = shared_library_path/"sum";
    
             //defining function types for lib constructors
             typedef boost::shared_ptr (sum_create_t)();
             typedef boost::shared_ptr (dot_product_create_t)(boost::shared_ptr);
             boost::function sum_creator;
             boost::function dot_product_creator;
    
             //importing SUM lib constructor(takes no arg)
             sum_creator = boost::dll::import_alias(   // type of imported symbol must be explicitly specified
                     parent_library_path,                            // path to library
                     "create_sum",                                   // symbol to import
                     dll::load_mode::append_decorations              // do append extensions and prefixes
             );
    
             //importing DOT_PRODUCT lib constructor(takes 1 arg of ptr to IOPERATION)
             dot_product_creator = boost::dll::import_alias(   // type of imported symbol must be explicitly specified
                     child_library_path,                                             // path to library
                     "create_dot_product",                                           // symbol to import
                     dll::load_mode::append_decorations                              // do append extensions and prefixes
             );
    
             //creating a ptr to SUM object
             boost::shared_ptr sum_ptr = sum_creator();
    
             //creating a ptr to DOT_PRODUCT object(passing above created SUM object ptr)
             boost::shared_ptr dot_product_ptr = dot_product_creator(sum_ptr);
             auto use_sum = true;
    
         const auto injector = di::make_injector(
               di::bind().to([&](const auto& injector) -> boost::shared_ptr {
                 if (use_sum)
                   return injector.template create<boost::shared_ptr>();
                 else
                   return injector.template create<boost::shared_ptr>();
             })
         );
    
         injector.create();
     }
    
  • 文件application_main.cpp

     #include "boost/shared_ptr.hpp"
     #include <boost/dll/import.hpp>
     #include "boost/function.hpp"
     #include 
     #include "ioperation.hpp"
    
     namespace dll = boost::dll;
    
     int main(int argc, char* argv[]) {
    
         //setting up paths to library(.so) files
         boost::filesystem::path shared_library_path(argv[1]);    // argv[1] contains path to directory with our plugin library
             boost::filesystem::path child_library_path = shared_library_path/"dot_product";
         boost::filesystem::path parent_library_path = shared_library_path/"sum";
    
         //defining function types for lib constructors
         typedef boost::shared_ptr (sum_create_t)();
         typedef boost::shared_ptr (dot_product_create_t)(boost::shared_ptr);
         boost::function sum_creator;
         boost::function dot_product_creator;
    
         //importing SUM lib constructor(takes no arg)
         sum_creator = boost::dll::import_alias(   // type of imported symbol must be explicitly specified
                 parent_library_path,                            // path to library
                 "create_sum",                                   // symbol to import
                 dll::load_mode::append_decorations              // do append extensions and prefixes
             );
    
         //importing DOT_PRODUCT lib constructor(takes 1 arg of ptr to IOPERATION)
         dot_product_creator = boost::dll::import_alias(   // type of imported symbol must be explicitly specified
                 child_library_path,                                             // path to library
                 "create_dot_product",                                           // symbol to import
                 dll::load_mode::append_decorations                              // do append extensions and prefixes
             );
    
         //creating a ptr to PARENT_PLUGIN_SUM objecti
         boost::shared_ptr sum_ptr = sum_creator();
    
         //creating a ptr to CHILD_PLUGIN_MULT object(passing above created PARENT_PLUGIN_SUM object ptr)
         boost::shared_ptr dot_product_ptr = dot_product_creator(sum_ptr);
    
         //executing calculate methods for object ptrs
         std::cout << "Plugin Name: " << sum_ptr->name() << std::endl;
         std::cout << "sum_ptr->calculate(1, 2)[expected=3]: " << sum_ptr->calculate(1, 2) << std::endl;
         std::cout << "Plugin Name: " << dot_product_ptr->name() << std::endl;
             std::cout << "dot_product_ptr->calculate(1, 2)[expected=5]: " << dot_product_ptr->calculate(1, 2) << std::endl;
     }   
    

以下是观察到的准确误差:

    + echo '=> Compiling libraries and application_main.cpp ...'
    => Compiling libraries and application_main.cpp ...

    + g++ -std=c++14 -fPIC -c -o libsum.o sum.cpp
    + g++ -shared -o libsum.so libsum.o
    + g++ -std=c++14 -fPIC -c -o libdot_product.o dot_product.cpp
    + g++ -shared -o libdot_product.so libdot_product.o
    + g++ -std=c++14 -lboost_filesystem -lboost_system -ldl application_main.cpp -o application_main
    + echo '=> Compilation completed. '
    => Compilation completed. 

    + echo '=> Executing ./application_main .'
    => Executing ./application_main .

    + ./application_main .
    [sum_constructor]
    [dot_product_constructor]
    Plugin Name: sum
    sum_ptr->calculate(1, 2)[expected=3]: 3
    Plugin Name: dot_product
    dot_product_ptr->calculate(1, 2)[expected=5]: 5
    [~dot_product_destructor]
    [~sum_destructor]
    + echo ==================================
    ==================================
    + echo '=> Compiling application_di.cpp ...'

    => Compiling application_di.cpp …
    + g++ application_di.cpp -lboost_filesystem -lboost_system -ldl -o application_di
    application_di.cpp: In lambda function:
    application_di.cpp:62:65: error: type/value mismatch at argument 1 in template parameter list for ‘template class boost::shared_ptr’
        62 |               return injector.template create<boost::shared_ptr>();
            |                                                                 ^~~~~~~
    application_di.cpp:62:65: note:   expected a type, got ‘sum_ptr’
    application_di.cpp:64:65: error: type/value mismatch at argument 1 in template parameter list for ‘template class boost::shared_ptr’
        64 |               return injector.template create<boost::shared_ptr>();
            |                                                                 ^~~~~~~~~~~~~~~
    application_di.cpp:64:65: note:   expected a type, got ‘dot_product_ptr’

特别声明:以上内容(图片及文字)均为互联网收集或者用户上传发布,本站仅提供信息存储服务!如有侵权或有涉及法律问题请联系我们。
举报
评论区(1)
按点赞数排序
用户头像