函数的结构:
在函数名和返回类型之间有一个调用约定:
下面叫我来创建并调用一下一个简单的动态库:
1.在VS中选择动态链接库创建:
包含一个头文件和一个需要用到的.cpp文件,
.cpp文件中创建需要的功能函数:
头文件中添加函数声明:
- #pragma once 作用是防止头文件被重复包含
- extern “C” 就是强制C++编译器用C语言的规则来编译函数,避免名字乱码,让DLL可以被所有语言通用调用
- _declspec(dllexport) 就是给函数开【对外权限】,让他可以被导出到DLL中,供外部程序调用
创建测试项目,并调用动态库:
编译没问题,运行出故障:把动态库项目的dll文件拷贝到测试项目和.exe文件同级目录中。
你问为什么?
这样运行程序时,可以快速找到.dll文件,防止找不到出现崩溃。
编译链接和运行加载是两个完全独立的阶段, 前者只需要.lib导入库,用来确认函数是否存在、地址正确,不检查DLL文件; 后者会真正去磁盘找DLL文件,加载到内存里。
- 问答题:请能够详细的说出,静态库和动态库两者有什么区别?
答:1. 代码嵌入:静态库编译时将代码完整复制到exe;动态库仅在运行时加载,多程序共享同一份代码。
2. 文件体积:静态库生成的exe体积大;动态库生成的exe体积小。
3. 更新维护:静态库更新需重新编译所有依赖程序;动态库直接替换文件即可。
4. 运行依赖:静态库不依赖外部文件;动态库运行时必须存在对应dll/so文件。
简答:静态库编译嵌入代码、体积大、更新需重编、无运行依赖;动态库运行加载、体积小、更新易、需依赖库文件。
- 问答题:请能够详细的说出,C接口的动态库和C++接口的动态库,有什么主要区别?
答:1. 名字修饰:C接口用 extern "C" 关闭名字修饰,函数名保持原始;C++接口默认开启名字修饰,函数名被编译器修改。
2. 跨语言支持:C接口可被C/C++/C#/Python等多语言调用;C++接口仅能被C++调用。
3. 函数重载:C接口不支持重载;C++接口支持重载(通过名字修饰区分不同重载函数)。
简答:C接口无名字修饰、ABI稳定,被几乎所有编程语言支持、不支持重载;C++接口有名字修饰、仅C++可用、支持重载。