制作动态库
- 打开VS2017,新建静态库项目
2. 项目内删除无关文件,再新建一个头文件mydll.h
3. 示例代码
// mydll.h
#ifndef MYDLL
#define MYDLL
#ifndef DLL_API
#define DLL_API _declspec(dllexport)
#else
#define DLL_API _declspec(dllimport)
#endif // !DLL_API
//声明导出的函数
DLL_API int mymult(int a, int b);
DLL_API int mydiv(int a, int b);
#else
#endif // !MYDLL
// mydll.cpp
#include "mydll.h"
int mymult(int a, int b) {
return (a * b);
}
int mydiv(int a, int b) {
return (a / b);
}
- 打开属性 ->C/C++ -> 预编译头 -> 预编译头,将使用(/Yu)改为不使用预编译头。
- 进行编译
使用动态库
- 创建一个usedll的空项目
2. 为了显着比较专业,我们在usedll项目目录下新建一个include保存静态库的.h头文件,新建一个lib目录保存静态库文件,并将上面制作好的dll文件、lib文件和.h文件放入对应目录下,如下图所示:
- 空项目下,新建一个usedll.cpp文件,试着包括头文件,尝试调用myadd方法,看看发生什么?
#include <iostream>
#include "./include/mydll.h"
using namespace std;
int main() {
cout << "10*2 = " << mymult(10, 2) << endl;
cout << "10 / 2 = " << mydiv(10, 2) << endl;
return 1;
}
4. 上述错误是缺少动态库,这里使用隐式加载,第一步加入#pragma comment(lib,“mydll.lib”),第二步在在项目属性下的链接器 -> 常规 -> 附加库目录里加入dll文件所在的目录路径,即mydll.lib所在目录。
#include <iostream>
#include "./include/mydll.h"
using namespace std;
#pragma comment(lib,"mydll.lib")
int main() {
cout << "10*2 = " << mymult(10, 2) << endl;
cout << "10 / 2 = " << mydiv(10, 2) << endl;
return 1;
}
- 显示结果
动态加载动态库方式
- 修改usedll.cpp
#include <iostream>
#include "./include/mydll.h"
#include <Windows.h>
using namespace std;
typedef int (*PMUL)(int a, int b); //定义函数指针
typedef int (*PDIV)(int a, int b); //定义函数指针
int main() {
//加载动态库文件
HMODULE myload = LoadLibrary("mydll.dll");
if (myload == NULL) {
cout << "加载动态库失败\n";
return 0;
}
PMUL mult = (PMUL)GetProcAddress(myload, "mymult"); // 获取接口,返回函数指针
PDIV div = (PDIV)GetProcAddress(myload, "mydiv");// 获取接口,返回函数指针
cout << "10*2 = " << mult(10, 2) << endl;
cout << "10 / 2 = " << div(10, 2) << endl;
FreeLibrary(myload);
return 1;
}
- 发生如下错误,原因是c++的编译动态库,其函数接口的名字会发生一些改变,所以上述的获取接口地址语句就会失败。解决方法有如下三种:
- 第一种方式
制作的动态库文件mydll.cpp改成mydll.c,然后重新编译生成。
- 第二种方式
将mydll.h中加入extern "C"语句,会指示编译器这部分代码按C语言(而不是C++)的方式进行编译。
#ifndef MYDLL
#define MYDLL
#ifndef DLL_API
#define DLL_API _declspec(dllexport)
#else
#define DLL_API _declspec(dllimport)
#endif // !DLL_API
//声明导出的函数
extern "C" DLL_API int mymult(int a, int b);
extern "C" DLL_API int mydiv(int a, int b);
#else
#endif // !MYDLL
- 第三种方式
在生成动态库项目下,新建模块定义文件,并定义好函数接口名称
// mydll.def
LIBRARY mydll
EXPORTS
mymult
mydiv
- 显示结果
转载:https://blog.csdn.net/wzyaiwl/article/details/116277824
查看评论