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

如何基于C++20 modules开发共享库?相关规范问题咨询

C++20 Modules 共享库开发(MSVC环境)正确实现方案

目前C++标准尚未对模块与动态链接的交互规则做统一约定,主流编译器中MSVC已经给出了生产可用的实现方案,具体规则如下:

核心逻辑

模块与传统头文件的本质差异是:模块接口单元仅会被编译1次生成二进制模块接口(BMI)文件,预处理器指令在编译模块阶段就已经生效,因此传统头文件通过宏切换__declspec(dllexport)/__declspec(dllimport)的方案完全不适用于模块。

MSVC 17.4及以上版本已经实现了自动转换逻辑:编译模块时标记为dllexport的符号,在消费者导入模块时会被编译器自动识别为dllimport,无需开发者手动处理。


完整实现步骤

1. 动态库侧代码示例

模块接口文件 math.ixx

export module math;

// 对外导出的函数统一加__declspec(dllexport)
export __declspec(dllexport) int add(int a, int b) {
    return a + b;
}

// 对外导出的类统一加__declspec(dllexport)
export class __declspec(dllexport) Calculator {
public:
    int mul(int a, int b) const;
};

模块实现文件 math_impl.cpp

module math;

int Calculator::mul(int a, int b) const {
    return a * b;
}

动态库编译配置

  • 开启C++20及以上标准:/std:c++20 或 /std:c++latest
  • 模块接口文件添加/interface编译选项,编译器会自动生成.ifc后缀的BMI文件
  • 链接生成DLL时会同步生成对应的.lib导入库

2. 消费者侧使用示例

业务代码 main.cpp

import math;
#include <iostream>

int main() {
    std::cout << add(1, 2) << std::endl;
    Calculator cal;
    std::cout << cal.mul(3, 4) << std::endl;
    return 0;
}

消费者编译配置

  • 开启与动态库侧一致的C++标准
  • 配置BMI搜索路径:将动态库生成的.ifc文件所在目录添加到/ifcSearchDir参数中,或通过/reference math=xxx/math.ifc直接指定对应模块的BMI路径
  • 链接时添加动态库对应的.lib导入库
  • 运行时将动态库生成的.dll文件放到可执行文件同目录即可

注意事项

  • 最低支持版本为Visual Studio 2022 17.4,更低版本的MSVC未实现自动转换逻辑,会出现链接错误
  • 不要在模块接口单元中使用宏判断切换dllexport/dllimport,编译模块时的预定义会被固化到BMI文件中,消费者导入时会识别到错误的链接标记
  • 上述规则为MSVC平台的专属实现,Clang、GCC的模块动态链接规则存在差异,跨平台场景需要单独适配对应编译器的规则

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 04:27:04