C/C++动态库和静态库+Cmake+Windows

文章目录

  • 问题由来
  • 探究过程
  • 探究结果
  • 示例工程
  • 工程介绍
    • 内容
    • 编译
      • 1、hwlib
      • 2、demo
    • 运行

问题由来

前段时间实习,遇到了一个很有意思的现象,使用cmake的link_libraries()在Windows下调用动态库(win下的动态库为dll)时,会出现如下错误:

fatal error LNK1107: 文件无效或损坏

由于之前一直是在Linux下开发程序,用此方法调用Linux的动态库(Linux下的动态库为so)时,从未出现过此问题,所以做了一下探究。

探究过程

由于不能使用cmake的link_libraries()链接动态库,所以换成target_link_libraries()+绝对路径的方法链接,但是仍然会报相同的错误。但在换成link_directories()+target_link_libraries()+动态库名称时,发现cmake会提示找不到(动态库名称).lib。这就很奇怪,明明链接的文件夹下就只有一个动态库,而且叫(动态库名称).dll,怎么cmake会需要(动态库名称).lib,难道Windows下的cmake只能链接静态库?

探究结果

这里要先介绍一下Windows和Linux的动态库和静态库的区别:
C/C++动态库和静态库+Cmake+Windows_第1张图片
在Windows下的动态库分为动态库本身.dll文件和动态库导入文件.lib,其中dll文件不参与编译参与运行,lib导入文件参与编译不参与运行,所以Windows下的cmake在想要调用dll动态库时,要链接dll动态库的导入文件.lib,而不是dll本身。Windows下的静态库则只有.lib。Linux的动态库和静态库则只有.os和.a。而Windows下的动态库的lib导入文件,需要在代码中加入__declspec(dlliexport)才可以生成,如下所示:

__declspec(dllexport) void HelloWorld();

示例工程

github工程链接

工程介绍

内容

1、hwlib为helloworld打印测试库,可以生成动态库和静态库,让下面的demo测试工程调用。
2、demo为调用hwlib库的测试工程,会生成基于动态库的可执行程序和基于静态库的可执行程序。

编译

1、hwlib

cd hwlib
mkdir build && cd build
cmake ..
cmake --build .
cmake --install .

会在C:\Program Files\下生成hwlib库文件夹,将其移动到demo目录下(demo目录已经包含hwlib库此步骤也可以忽略)。

2、demo

cd demo
mkdir build && cd build
cmake ..
cmake --build .

运行

编译后,在demo/build/下有两个可执行程序,main_static和main_shared,其功能都是在终端打印HelloWorld字符串,但是main_static可以直接执行,main_shared则需要依赖hwlib.dll动态库,如运行main_shared出现找不到动态库的错误,则可以将hwlib.dll放在和main_shared同一个文件夹下。

你可能感兴趣的:(windows,c++,linux)