前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >visual studio静态,动态链接库开发工具简单使用

visual studio静态,动态链接库开发工具简单使用

作者头像
byronhe
发布2021-06-25 10:46:06
1K0
发布2021-06-25 10:46:06
举报
文章被收录于专栏:Tech Explorer

这是2011年8月份做过的一点实验,查了MSDN等等很多资料,基本搞明白了。

这里我不会使用visual studio的图形界面工具,作为专业人士,还是搞懂自己的工具是怎么运转的,这样比较好。

要使用的是visual studio的命令行工具,其实和gcc那堆工具对应关系挺明显的,大致如下:

gcc

cl

ar

lib

ld

link

文件后缀对应关系:

gcc

cl

.a

.lib

.so

.dll

.o

.obj

新手注意:这个命令提示符是"开始菜单"–»“Microsoft Visual studio”–»“Visual Tools” 那里的提示符,其实就是设置过一些环境变量的cmd。

先把实验代码贴出来(可以先跳过不看),共有五个文件:

1.build.bat

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

""C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat"" x86 cd dynamic del /f /Q * cl /LD ..\ext.c del ext.obj cl ..\main.c /link ext.lib del main.obj cd .. cd static del /f /Q * cl /c ..\ext.c lib ext.obj del ext.obj cl ..\main-static.c /link ext.lib del main*.obj main*.exp main*.lib cd ..

2.库的头文件,ext.h

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27

#ifndef EXT_H #define EXT_H #ifdef Import #define Dll __declspec(dllimport) #else #ifdef Export #define Dll __declspec(dllexport) #else #define Dll #endif #endif #include <stdio.h> Dll typedef struct { int i; char c; } st; Dll extern int num; Dll void fun(); Dll extern st s; #endif

3.库的实现文件,ext.c

1 2 3 4 5 6 7

#define Export #include "ext.h" st s={24,'h'}; int num=0; void fun(){ printf("hello,i am in lib. num=%d\n",num++); }

4.以动态链接库方式使用这个库的程序代码,main.c

1 2 3 4 5 6 7 8 9 10 11 12

#define Import #include "ext.h" #include "windows.h" #include<stdio.h> int main(){ fun(); printf("num=%d\n",num); fun(); printf("num=%d\n",num); printf("st i=%d c=%c \n",s.i,s.c); }

5.以静态链接库方式使用这个库的程序代码,main-static.c

1 2 3 4 5 6 7 8 9 10 11

#include "ext.h" #include "windows.h" #include<stdio.h> int main(){ fun(); printf("num=%d\n",num); fun(); printf("num=%d\n",num); printf("st i=%d c=%c \n",s.i,s.c); }

一,静态链接库 要给用户提供静态链接库,都要提供哪些文件呢?.h头文件+.lib库文件  先问个问题: 使用库的最简单方式是什么?当然是不使用库! 不使用库谁不会啊?使用如下命令:

1

cl main-static.c ext.c

在当前目录下,就会编译,链接成一个main-static.exe,执行一下,没有问题!

再问个问题:除了exe文件,还看见了什么?有ext.obj, main-static.obj, main-static.lib ,main-static.exp .

.obj文件是目标文件(object file), .lib文件是静态库文件(msdn中称为导入库), .exp文件,导出文件,辅助作用(参看这里和这里) 可以猜想,用cl直接编译生成exe的过程,是

  1. ext.c—»ext.obj
  2. main-static.c–»main-static.obj
  3. main-static.obj—»main-static.exp+main-static.lib
  4. ext.obj+main-static.lib+main-static.exp—»main-static.exe

的过程

我尝试了改换参数顺序,即用命令

1

cl ext.c main-static.c

发现main-static.exp + main-static.lib换成了ext.lib+ext.exp 这说明是cl是先把.c文件都生成为obj文件,然后把第一个命令行参数指定xxx.c的xxx.obj文件再生成为xxx.lib+xxx.exp文件   这和静态链接有什么关系呢?关系密切啊! 把除了ext.lib 以外的所有生成文件删除,运行如下命令:

1

cl main-static.c /link ext.lib

就可以看见,生成了main-static.exe,运行正常。ext.lib就是静态链接库。 其实,这就是一个静态链接的过程。 

 静态链接的第一步,怎么由ext.c生成obj文件?查msdn(或者 命令cl /?)可知,给cl提供/c参数就可以了,先清掉那堆文件,运行

1

cl /c ext.c

成功生成ext.obj.同理可以生成main-static.obj。 严格来说编译已经完成,接下来的,都是链接过程。

第二步,怎么从obj文件生成.lib文件(加/DEF参数,就可以同时生成.exp文件)

1

lib ext.obj

就生成了ext.lib 第三步,怎么从main-static.c + ext.lib 生成exe

1

cl main-static.c /link ext.lib

需要注意的是,头文件一定要可以找到。

二,动态链接库 visual studio的动态链接分为显式链接和隐式链接两种(http://msdn.microsoft.com/zh-cn/library/253b8k2c(v=vs.80).aspx),显式链接就是自己写代码调用win32 Api加载dll文件,要使用LoadLibrary, GetProcAddress(), FreeLibrary()这些函数,这个方法几乎不需要工具,就不说了,看看msdn的例子就明白了。 以下说的都是隐式链接

visual studio的动态链接库使用很与众不同,竟然需要提供三种文件:.h+.lib+.dll文件,诡异的是,这个.lib文件和静态链接库里的.lib文件其实不一样! 更诡异的是,用户链接的时候,其实不需要.dll文件!

对比之下,linux下的gcc,若是动态链接库,需要的是.so+.h 文件(.so相当于.dll),这是显著的差异。

参看csdn(http://msdn.microsoft.com/zh-cn/library/3y1sfaz2(v=vs.100).aspx)可知,和静态链接不同的是,动态链接需要对库的源代码进行改动,添加

1

__declspec( dllimport )

 或

1

__declspec( dllexport )

补充:也可以用def文件,不过我没试过,参看 http://msdn.microsoft.com/zh-cn/library/0b9xe492.aspx 和 http://msdn.microsoft.com/zh-cn/library/28d6s79h.aspx 。

这个时候要注意,__declspec( dllimport )和__declspec( dllexport ) 的使用是不一样的,在库里导出的符号(函数,变量等,可以用dumpbin查看)应该使用__declspec( dllexport ) ,而使用库的代码,在包含头文件后,要有这些符号的声明,要看到__declspec( dllimport )形式的声明,所以这是有区别的。在上面ext.h里,我用了一个宏Dll来统一处理。 

处理完源代码,就可以编译了。

第一步,生成obj文件,

1

cl /c ext.c

第二步,由obj文件生成dll文件+lib文件,

1

cl /LD ext.obj

或者也可以用

1

link /DLL ext.obj

可以看到,生成了ext.dll , ext.exp, ext.lib 三个文件,其中的ext.lib 这个文件和静态链接时生成的ext.lib文件是不一样的!而且ext.dll在main.c的链接过程中是用不着的! (此时已经生成了dll文件,要是使用显式链接,就把dll文件弄走,自己写代码去啦),继续隐式链接 第三步,不妨移走ext.dll,然后编译

1

cl main.c /link ext.lib

可以看到生成main.exe,但是运行一下,会报告找不到ext.dll,当然找不到啦,只要把ext.dll移到当前目录下(或在dll文件查找路径中的一个中)即可正常运行。

   注:dll文件查找路径参看 http://msdn.microsoft.com/zh-cn/library/7d83bc18(v=vs.80).aspx

这个领域关注的人少,鄙人理解浅薄,错误难免,欢迎指正。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2011-11-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
日志服务
日志服务(Cloud Log Service,CLS)是腾讯云提供的一站式日志服务平台,提供了从日志采集、日志存储到日志检索,图表分析、监控告警、日志投递等多项服务,协助用户通过日志来解决业务运维、服务监控、日志审计等场景问题。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档