动态库加载的 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’
特别声明:以上内容(图片及文字)均为互联网收集或者用户上传发布,本站仅提供信息存储服务!如有侵权或有涉及法律问题请联系我们。
举报