动态库和静态库
动态库(.dll)和动态链接库(.lib)
动态库工程 会生成.dll文件(包含代码实现)、.lib文件(包含代码的声明)动态链接库
静态库(.lib)
静态库工程 会生成.lib文件 包含代码的声明和实现
给其他人链接库的时候,除了.lib文件还要给出头文件,否则别人将不知道如何调用。
调用动态库和静态库
以vs2015为例
1.打开项目 -> 项目属性 -> 配置属性 -> VC++目录 -> (附加)包含目录 加入.h
2.打开项目 -> 项目属性 -> 配置属性 -> VC++目录 -> (附加)库目录 加入.lib目录
3.打开项目 -> 项目属性 -> 配置属性 -> 链接器 -> 输入 -> 附加依赖项 加入.lib文件 分号隔开
4.工程调用dll时首先在工程文件目录中查找dll,找不到后在C:\Windows\System32 中找。
请使用宏定义$()和相对路径配置项目
所以我们自己项目简单调用dll时就把生成的dll文件复制到工程目录中,
如果经常用可以把dll文件放到C:\Windows\System32中
ffmpeg等c语言的库!!!!!!!!!!!错了三次以上
引入头文件一定要加入 extern “C” {}
VS常见问题
调试
多个项目 更改了某一动态库时 要在启动项目中添加依赖 使其他项目编译一遍 不然代码错乱
解决方案
解决方案中含有多个项目时 附加库路径会自动添加到启动项的debug目录中 而编译库项目并不会将更改生成的lib放到启动项目的debug中 导致.lib引入出错—-8月1日掉坑
库项目如果添加了新的结构 如结构体 库项目新编译的dll文件 需要放到启动项目的启动目录下面—-8月1日掉坑
启动项目 dll 要和exe放在一起
#常见问题
函数未声明
原因1.头文件冲突或者函数重名
解决办法:重名函数头文件在用到的时候再引入头文件
例如adb sysdeps.h和 fork read/close等冲突
#调试
使用宏定义去除调试代码
ifdef _DEBUG
//dosomething
elseif
//dosomething
endif
/MD、/MDd 和 /MT、/MTd之间的区别
那个'd'是代表DEBUG版本,没有'd'的就是RELEASE版本
/MT是 "multithread, static version ” 意思是多线程静态的版本,定义了它后,编译器把 LIBCMT.lib 安置到OBJ文件中,让链接器使用LIBCMT.lib 处理外部符号。
/MD是 "multithread- and DLL-specific version” ,意思是多线程DLL版本,定义了它 后,编译器把 MSVCRT.lib 安置到OBJ文件中,它连接到DLL的方式是静态链接,实际上工作的库是MSVCR80.DLL。
即:
静态运行时库:LIBCMT.lib
动态运行时库:MSVCRT.lib + MSVCR80.DLL
单线程运行时库选项/ML和/MLd在VS2003以后就被废了。
/MT和/MTd表示采用多线程CRT库的静态lib版本。该选项会在编译时将运行时库以静态lib的形式完全嵌入。该选项生成的可执行文件运行时不需要运行时库dll的参加,会获得轻微的性能提升,但最终生成的二进制代码因链入庞大的运行时库实现而变得非常臃肿。当某项目以静态链接库的形式嵌入到多个项目,则可能造成运行时库的内存管理有多份,最终将导致致命的“Invalid Address specified to RtlValidateHeap”问题。另外托管C++和CLI中不再支持/MT和/MTd选项。
/MD和/MDd表示采用多线程CRT库的动态dll版本,会使应用程序使用运行时库特定版本的多线程DLL。链接时将按照传统VC链接dll的方式将运行时库MSVCRxx.DLL的导入库MSVCRT.lib链接,在运行时要求安装了相应版本的VC运行时库可再发行组件包(当然把这些运行时库dll放在应用程序目录下也是可以的)。 因/MD和/MDd方式不会将运行时库链接到可执行文件内部,可有效减少可执行文件尺寸。当多项目以MD方式运作时,其内部会采用同一个堆,内存管理将被简化,跨模块内存管理问题也能得到缓解。