文章目录
-
-
- 说明
- 动态库和静态库联系与区别
- 静态库(static lib)注意事项
- 动态库(dynamic lib + dll)注意事项
- 常见问题
- 联系博主
-
说明
- 本文是在综合CSDN博客的基础上,再加上博主自己实践总结所写
- 博主之前曾写过一篇博文介绍该内容,但那篇文章有囫囵吞枣之意,所以“再谈”
- 本文若有错误之处,请在评论留言,及时回复
- 本文涉及到的环境均为 Windows 10 + VS 2013
动态库和静态库联系与区别
- 这是博主之前写的一篇入门文章,可以结合的看
VS下静态库与动态库的生成与使用
- 其它相关文章,博主推荐
static lib和dynamic lib
VS2013动态库文件的创建及其使用详解
c++导出库
静态库(static lib)注意事项
- 新建静态库工程
- 正常写 .h 和 .cpp
- 新建测试工程
- 编辑 test.cpp
- 将 .lib 复制到 test.cpp
- 【属性 - 链接器 - 附加依赖项】加入 .lib 名称
- 编译运行
动态库(dynamic lib + dll)注意事项
- 新建动态库生成工程 DLLGenerater
- 选择 控制台应用程序,其它请读者自行尝试,大同小异
- 选择 DLL
- 勾选 空项目
- 预编译头VS 默认强制勾选
- 安全开发生命周期(SDL)检查 选不选择无所谓
- 新建若干 .h 和 .cpp,每个 .h 又可包括若干内容
- math.h 和 math.cpp 示例代码(见文末所附代码)
- animal.h 和 animal.cpp 示例代码(见文末所附代码)
- 不写 main 函数
- 如果想验证代码的正确性,可在属性将默认类型的配置类型像彗星修改为**.exe**进行编译运行
- 编译即可,在 …/Debug 或者 …/Release 目录下生成 DLLGenerater.lib 和 DLLGenerater.dll
- 新建测试动态库工程 DLLUser
- 新建 test.cpp
- 复制 math.h 和 animal.h 到 test.cpp 同一级目录
- 复制 DLLGenerater.lib 和 DLLGenerater.dll 也到 test.cpp 同一级目录
- DLLUser 属性的链接器的附加依赖项中添加 DLLGenerater.lib
- 编辑 test.cpp 的内容(见文末所附代码)
- 编译运行成功
- 附:使用 DLLGenerater.dll 的几种方式
- 编译运行时候
- 第一种方式
- .h、.lib、.dll、随 test.cpp 同一级目录
- 第二种方式
- .h、.lib 随 test.cpp 同一级目录
- 系统环境变量的 system 的 path 加入 .dll 的路径(Windows 下可能需要重启电脑)
- 第三种方式
- .h 随 test.cpp 同一级目录
- test.cpp 中加入
#pragma comment(lib,"DLLGenerater.lib")
- 系统环境变量的 system 的 path 加入 .dll 的路径(Windows 下可能需要重启电脑)
- 第四种方式(类似于配置第三方库)
- 【项目属性 - VC++目录 - 包含路径】 添加 .h 路径
- 【项目属性 - VC++目录 - 包含库目录】 添加 .lib 路径
- 【项目属性 - 链接器 - 附加依赖项】 写入具体的 .lib 名称
- 系统环境变量的 system 的 path 加入 .dll 的路径(Windows 下可能需要重启电脑)
- 第一种方式
- 脱离VS运行时候
- 第一种方式
- 将 .dll 和 .exe 放在一起
- 第二种方式(这个是我猜测的,未经实际验证)
- 预先就在文件中写入 .dll 的相对路径,这样的话可以在程序打包发布时候将 .dll 放入指定文件夹,具体可参见现有软件的安装程序(如参看 QQ 的安装程序路径)
- 第一种方式
- 编译运行时候
- 附:上述所提及代码
math.h
#ifndef _MATH_H_
#define _MATH_H_
#include <cmath> // 记得加头文件
// 有时候觉得写得麻烦
// 那么可以 typadef
#ifndef MY_DLL // 条件编译
#define MATH_EXPORT __declspec(dllexport)
#endif
// 对于函数(全局函数,成员函数等)
// __declspec(dllexport) 写在最前面
// 然后是返回值,函数名,形参
__declspec(dllexport) int add(int a, int b);
// 对于类,如果要导出所有函数
// 那么 __declspec(dllexport) 写在 class 和 类名中间
class __declspec(dllexport) ExportAllDll {
public:
float getSin(float theta); // 普通成员函数
static void printClass(); // 静态函数
private:
const double PI = std::acos(-1);
// 私有函数,不会导出!!!并且该导出无实际意义
float __getTan(float theta);
};
// 对于类,如果要导出部分函数
// 则类名前不加 __declspec(dllexport)
// 而是在要导出的函数前面加上 __declspec(dllexport)
class ExportPartDll {
public:
__declspec(dllexport) float getSqrt(float num); // 导出
float getAbs(float num); // 不导出
};
// 也可以这样导出函数
MATH_EXPORT void getMatrix();
#endif // _MATH_H_
math.cpp
#include "math.h"
#include <iostream>
// .cpp 实现文件一概不写 __declspec(dllexport)
int add(int a, int b){
return a + b;
}
// 类函数的实现记得加上类名
float ExportAllDll::getSin(float theta){
return std::sinf(theta * PI / 180);
}
// 这里不写 static
void ExportAllDll::printClass(){
std::cout << "printClass\n";
}
// 私有函数的实现
float __getTan(float theta){
return 90.0f;
}
// 这个是要导出的函数
float ExportPartDll::getSqrt(float num){
return std::sqrt(num);
}
// 这个不导出
float ExportPartDll::getAbs(float num){
return std::abs(num);
}
// typedef __declspec(dllexport) MY_DLL 的使用
void getMatrix(){
std::cout << "This is matrix.\n";
}
animal.h
#ifndef _ANIMAL_H_
#define _ANIMAL_H_
__declspec(dllexport) void printZoo();
#endif // _ANIMAL_H_
main.cpp
#include "animal.h"
#include <iostream>
void printZoo(){
std::cout << "printZoo()\n";
}
test.cpp
#include "math.h"
#include "animal.h"
#include <iostream>
int main(){
// 测试全局函数
int a = 1, b = 2;
std::cout << add(a, b) << std::endl;
// 测试导出类
ExportAllDll ad;
std::cout << ad.getSin(30) <<std::endl;
ExportAllDll::printClass();
// 测试类导出函数
ExportPartDll pd;
std::cout << pd.getSqrt(9.0f) << std::endl;
// std::cout << pd.getAbs(-6.6f) << std::endl;
// 测试全局函数
getMatrix();
// 测试全局函数
printZoo();
return 0;
}
常见问题
C++ dll库只生成dll文件,而未生成lib文件的问题
Error LNK2001 无法解析的外部符号 的几种情况及解决办法
联系博主
评论会尽快回复