You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++ boost::di结合Boost.dll动态加载的依赖注入绑定报错问题

问题概述

联合使用C++依赖注入库boost::di与动态库加载库Boost.dll开发时触发编译错误,验证流程拆分为两个环节:

  • 动态库加载功能测试
  • 抽象类与动态加载实现类的依赖注入绑定
    目前动态库加载功能已验证可正常运行,编写DI绑定逻辑时触发类模板期望类型参数但未收到对应类型的编译错误。
项目文件逻辑
  • ioperation.hpp:定义抽象接口ioperation,声明name() const、calculate(float x, float y)纯虚方法与虚析构函数
  • sum.cpp:编译为libsum.so动态库,实现sum类继承ioperation接口,通过BOOST_DLL_ALIAS宏导出无参工厂方法create_sum用于创建类实例
  • dot_product.cpp:编译为libdot_product.so动态库,实现dot_product类继承ioperation接口,类依赖ioperation类型指针完成点积计算,通过BOOST_DLL_ALIAS宏导出接收ioperation指针参数的工厂方法create_dot_product
  • application_main.cpp:未使用DI的测试代码,可正常编译运行:通过boost::dll::import_alias导入两个动态库的工厂方法,创建实例后调用calculate方法,输出结果符合预期
  • application_di.cpp:使用boost::di的业务代码,先通过Boost.dll导入两个库的工厂方法,提前创建sum_ptr、dot_product_ptr两个boost::shared_ptr<ioperation>类型实例指针;在通过di::make_injector构建注入器、绑定ioperation接口的lambda逻辑中,错误将变量名sum_ptr、dot_product_ptr作为模板参数传入boost::shared_ptr,触发编译错误
报错信息

在lambda函数内调用injector.template create<boost::shared_ptr<sum_ptr>>()与injector.template create<boost::shared_ptr<dot_product_ptr>>()时,编译器提示boost::shared_ptr模板参数期望传入类型,但实际传入了变量sum_ptr、dot_product_ptr,编译失败。

错误根因

C++模板参数要求传入编译期可确定的类型/常量,sum_ptr、dot_product_ptr是运行时创建的实例变量,本身不是类型,不能作为模板参数传入尖括号内。

正确绑定方案

动态加载场景下,已经通过Boost.dll拿到的实例不需要再通过DI容器重新创建,直接将现成实例、动态导入的工厂绑定到注入器即可,参考实现如下:

// 1. 先完成动态库加载,导入导出的工厂方法
auto create_sum = boost::dll::import_alias<boost::shared_ptr<ioperation>()>(
    boost::filesystem::path("libsum.so"), "create_sum"
);
auto create_dot_product = boost::dll::import_alias<boost::shared_ptr<ioperation>(ioperation*)>(
    boost::filesystem::path("libdot_product.so"), "create_dot_product"
);

// 2. 构建DI注入器,完成接口绑定
auto injector = di::make_injector(
    // 绑定无依赖的sum实现:直接调用动态库导入的工厂返回实例
    di::bind<ioperation>().named(di::type<sum>).to([&](){
        return create_sum();
    }),
    // 绑定有依赖的dot_product实现:从注入器解析依赖的ioperation实例,传入动态库工厂
    di::bind<ioperation>().named(di::type<dot_product>).to([&](const auto& inj){
        auto sum_op = inj.create<boost::shared_ptr<ioperation>>(di::named<sum>);
        return create_dot_product(sum_op.get());
    })
);

// 3. 业务侧从注入器取实例使用
auto sum_op = injector.create<boost::shared_ptr<ioperation>>(di::named<sum>);
auto dot_op = injector.create<boost::shared_ptr<ioperation>>(di::named<dot_product>);

注意事项

  • boost::di支持直接绑定运行时生成的现成实例、工厂函数,不需要强制所有实例都由DI容器完成构造
  • 同一抽象接口绑定多个实现时,使用di::named做命名区分即可,禁止将运行时变量名写入模板尖括号
  • 所有出现在模板尖括号<>内的参数,必须是编译阶段就能确定的类型、常量表达式

内容的提问来源于stack exchange,提问作者Sukhdeep Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 12:39:15