MSVC编译动态库

简介: MSVC编译动态库

本文跟《Linux环境编译动态库》 使用同样的项目 universe,下载之后,放到 D盘,如下:

编译链接命令如下:

cl.exe /c earth.c moon.c sun.c 
link.exe /DLL /DEBUG /EXPORT:sun_rotate /EXPORT:moon_rotate /EXPORT:earth_rotate /OUT:star.dll earth.obj moon.obj sun.obj 
cl.exe /c zeus.c
link.exe /DEBUG /OUT:zeus.exe zeus.obj star.lib

我们再用 dumpbin 来查看一下 zeus 是否依赖 star.dll ,如下:

dumpbin /DEPENDENTS zeus.exe



Windows 的动态库跟 Linux 的动态库有点不一样,Windows 使用动态库需要一个 lib 导入库来支持编译。如下:

上图中,这个 star.lib 不是静态库,而是动态库的导入库。给 link.exe 使用的。只有链接的时候才需要 star.lib ,生成 exe 之后可以把 star.lib 删掉,也不会影响 exe 的运行。exe的运行只需要 star.dll 。

star.lib 是通过 上面命令的 /EXPORT:xxx 导出来的,上面的命令中,我导出了 3个函数,所以要写 3次,很麻烦,其实 link.exe 也支持 DEF 文件的方式导入。

在 universe 目录新建一个 star.def 文件,内容如下:

EXPORTS
    sun_rotate
    moon_rotate
    earth_rotate

然后执行以下命令重新编译动态库:

link.exe /DLL /DEBUG /DEF:star.def /OUT:star.dll earth.obj moon.obj sun.obj

上图中的 star.pdb 实际上是调试文件,windows 是把调试信息单独文件存放的。只有使用了 /DEBUG 选项,才会生成 pdb 文件。

提前剧透一下,msys2 + msvc 编译 FFmpeg 的时候,FFmpeg 的动态库函数也是通过 def 文件导出来的,如下:


以上都是使用 cl.exe 跟 link.exe 手动生成 动态库,现在用 vs2019 演示一下如何创建跟编译一个动态库。

由于 vs2019 的默认动态库项目会引入一些其他的配置,我们只是简单的 3 个C文件,所以不选 DLL 项目,直接创建 空白项目,然后改项目类型就行。

创建一个空白项目,把项目命名为 star

然后再打开项目配置,设置 Platform 跟 General ➜ Configuration Type,如下:

然后把 3 个文件 earth.c moon.c sun.c 复制到 star 目录,如下:

然后点击 Add ➜ Exiting Item 添加3个文件进去解决方案,如下:

这样默认只会生成 star.dll ,但是不会生成 star.lib 导入库的,因此我们把 star.def 文件也拷贝过去项目目录(跟C文件同目录),

然后设置 Linker ➜ All Options ➜ Module Definition File ,如下:

应用之后,就会发现 Command Line 里面就出现 /DEF:"star.def" 选项了。

重点: Command Line 特别好用,无论是 C/C++ 的编译参数,还是 lib.exe 生成静态库的参数,还是 link.exe 编译exe或者动态库的参数。都在 各自的 Command Line ,你可以通过这个 Command Line 查看实际运行的参数,看看有没问题,不需要rebuild 从日志里面看。


现在再重新 rebuild 一下,就会生成 star.lib 跟 star.dll 了,如下:

参考资料:

1,《MSVC EXPORT用法》

目录
相关文章
|
开发框架 前端开发 JavaScript
从前端到后端——完整的Web开发指南
【2月更文挑战第1天】Web开发已经成为了现代软件开发中不可或缺的一部分。无论是前端还是后端,都扮演着重要的角色。本文将从前端到后端,介绍完整的Web开发流程和技术栈,帮助初学者快速入门Web开发。
|
安全 Java Linux
CentOS7 部署ElastiFlow网络流量分析平台
CentOS7 部署ElastiFlow网络流量分析平台
1271 0
CentOS7 部署ElastiFlow网络流量分析平台
|
存储 数据安全/隐私保护
RPMB说明与使用(Replay Protected Memory Block)
RPMB说明与使用(Replay Protected Memory Block)
3998 0
|
编译器 C语言 C++
MinGW安装gcc
MinGW安装gcc
338 0
|
关系型数据库 MySQL Java
修改XWiKi连接的数据库遇到的问题
修改XWiKi连接的数据库遇到的问题
218 0
|
Rust JavaScript 安全
Rust 笔记:Rust 语言中的字符串
Rust 笔记:Rust 语言中的字符串
415 0
|
关系型数据库 MySQL
MySQL Command line client窗口闪退原因
MySQL Command line client窗口闪退原因
422 0
|
Java 编译器 API
4.3 Lambda表达式的性能与限制:在某些情况下避免使用Lambda表达
4.3 Lambda表达式的性能与限制:在某些情况下避免使用Lambda表达
2150 0
|
JavaScript
LeafLet实战-扩展工具栏指南
熟悉LeafLet的都知道,LeafLet自带的工具条只有两个按钮,一个放大和缩小。日常业务中,会用到许多的实用工具,比如测距,量测,如何扩展默认的工具条呢?解决方案如下两种:第一、自己基于dom创建页面元素,并挂载在其默认的工具栏中。第二、基于Leaflet.EasyButton进行扩展。
604 0
LeafLet实战-扩展工具栏指南