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

如何用CMake搭配MinGW直接链接DLL文件?附项目配置方案

Windows下C++使用DLL库的说明及CMake配置

核心问题解答

在Windows系统中,C++代码不能直接链接DLL文件。DLL是运行时加载的二进制文件,编译器的链接阶段需要依赖对应的**导入库(.lib文件)**来获取DLL中导出符号(函数、类、变量等)的信息,才能生成可执行文件。网上提到的"无法直接链接DLL"或"需转为LIB文件",本质就是指必须通过导入库完成编译链接阶段的符号关联。

如果只有DLL文件而没有对应的.lib导入库,只能通过动态加载API手动加载DLL并调用其中的函数,这种方式不需要链接.lib,但代码实现会更繁琐。


有导入库时的CMake配置(常规场景)

假设你的libs目录下实际存在与DLL同名的导入库(first.lib、second.lib,通常DLL发布时会配套提供),对应的CMakeLists.txt可以按以下方式编写,适配你给出的项目结构:

# 最低CMake版本要求
cmake_minimum_required(VERSION 3.15)

# 项目名称
project(my_project)

# 设置C++标准
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 创建可执行目标
add_executable(my_target app/main.cpp)

# 引入头文件目录(DLL的函数/类定义)
target_include_directories(my_target PRIVATE include)

# 指定导入库所在目录
target_link_directories(my_target PRIVATE libs)

# 链接导入库(链接器会自动匹配同名的.lib文件)
target_link_libraries(my_target PRIVATE first second)

# 编译后自动复制DLL到可执行文件输出目录(运行时需要)
add_custom_command(TARGET my_target POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy_if_different
        "${PROJECT_SOURCE_DIR}/libs/first.dll"
        "${PROJECT_SOURCE_DIR}/libs/second.dll"
        $<TARGET_FILE_DIR:my_target>
)

配置说明

  • target_include_directories:让编译器找到include目录下的头文件,这些头文件包含DLL导出符号的声明。
  • target_link_directories:告诉链接器去哪里找导入库文件。
  • target_link_libraries:将可执行目标与导入库链接,链接器会自动寻找libs目录下的first.lib和second.lib。
  • add_custom_command:编译完成后把DLL复制到exe所在目录,避免运行时因找不到DLL而报错。

无导入库时的动态加载方案

如果确实只有DLL文件,没有对应的.lib,可以通过Windows提供的LoadLibrary、GetProcAddress等API手动加载DLL并调用函数。示例代码如下(以first.dll为例):

#include <windows.h>
#include <iostream>

// 根据DLL导出函数的签名,定义对应的函数指针类型
typedef void (*FirstExportedFunc)();

int main() {
    // 加载DLL文件
    HMODULE firstDll = LoadLibrary(L"first.dll");
    if (!firstDll) {
        std::cerr << "加载first.dll失败,错误码:" << GetLastError() << std::endl;
        return 1;
    }

    // 获取导出函数的地址
    FirstExportedFunc func = reinterpret_cast<FirstExportedFunc>(GetProcAddress(firstDll, "FirstExportedFunc"));
    if (!func) {
        std::cerr << "获取函数地址失败,错误码:" << GetLastError() << std::endl;
        FreeLibrary(firstDll);
        return 1;
    }

    // 调用DLL中的函数
    func();

    // 释放DLL
    FreeLibrary(firstDll);

    return 0;
}

这种情况下,CMake只需编译可执行文件,无需链接库,同样可以用add_custom_command将DLL复制到输出目录。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 05:34:55