C和C++中动态链接库的创建和链接(原创,装载请注明原处)
c和c++中动态链接库的创建和链接
1.创建dll(动态链接库)-c++方式
1.创建dll(动态链接库-c++方式)
1.在vs(以vs2017为例)中创建dll动态链接库。
解决方案名称为:mydll
项目名称为:dll1
2.创建头文件dll1.h
输入如下代码:
#pragma once #ifdef my_dll_exp #else #define my_dll_exp _declspec(dllimport)////当编译时,头文件不参加编译,所以.cpp文件中先定义,后头文件被包含进来,因此外部使用时,为dllexport,而在内部编译时,则为dllimport #endif //创建一个常量 my_dll_exp extern const double pi; //创建一个测试用的函数 void my_dll_exp hello(); //创建一个测试用的类 class my_dll_exp calculate { public: double add(double a, double b); double sub(double a, double b); double mult(double a, double b); double divd(double a, double b); };
3.创建dll1.cpp(如存在则不用创建)
输入如下代码:
#include "stdafx.h" #include "dll1.h" //注意以上两个头文件的相对顺序不能改变 #include <iostream> #define my_dll_exp _declspec(dllexport) //导出常量 const double pi = 3.14; //导出函数 void hello() { std::cout << "hello world!" << std::endl; } //导出类中的函数 double calculate::add(double a, double b) { return a + b; } double calculate::sub(double a, double b) { return a - b; } double calculate::mult(double a, double b) { return a * b; } double calculate::divd(double a, double b) { if (b == 0) return 0; return a / b; }
4.生成即可完成c++版动态链接库的创建
注意:动态链接库文件不能直接执行
2.链接dll(动态链接库-c++方式)
1.隐式链接
1.准备
dll1.h(dll1项目目录中)
dll1.lib(解决方案的debug中)
dll1.dll(结局方案的debug中)
2.创建一个测试用隐式链接动态链接库的项目
此处以空项目为例
项目名称为:testdll1
此处为了方便,将dll1.h,dll1.lib,dll1.dll放入到新建的项目目录下。
3.右击解决方案,选择属性。在通用属性中的启动项目中选择当前选中内容,确认即可。
4.右击要链接dll的项目testdll1,选择属性,进行配置。
(1)配置属性->vc++目录->在"包含目录"里添加头文件dll1.h所在的目录
(2)配置属性->vc++目录->在"库目录"里添加头文件dll1.lib所在的目录
(3)配置属性->链接器->输入->在"附加依赖项"里添加dll1.lib(若有多个lib则以空格隔开)
4.将dll1.dll文件放入到创建的项目的目录下或是解决方案的debug目录下
5.创建testdll1.cpp
输入如下测试代码:
#include "dll1.h" #include <iostream> //隐式调用dll using namespace std; int main() { cout << pi << endl;//测试输出常量 hello();//测试函数 //测试类 calculate calc; cout << "3 + 2 = " << calc.add(3, 2) << endl; cout << "4 - 1 = " << calc.sub(4, 1) << endl; cout << "3 * 2 = " << calc.mult(3, 2) << endl; cout << "4 / 2 = " << calc.divd(4, 2) << endl; cin.get();//暂停 }
输出结果:
2.显式链接
显示链接可以在执行过程中随时加载dll文件,也可以随时卸载dll文件,这是隐式链接所无法作到的,所以显式链接具有更好的灵活性,对于解释性语言更为合适.
显示链接主要是使用loadlibrary()函数。此处只说明显示链接dll的导出函数的使用方法,导出类的使用比较复杂,将在我的其他文章中说明。
1.创建测试用空项目testdll2
2.将dll1.dll放入到testdll2项目目录下
3.创建testdll2.cpp
输入如下代码:
//显示链接dll-使用getprocaddress获取函数的名字会有所改变需要使用dumpbin.exe查询 #include <windows.h>//加载头文件 #include <iostream> using namespace std; //设置全局变量hinst用于存储dll句柄并加载动态链接库 hinstance hinst = nullptr; //声明函数指针 typedef void(*hello)(); int main() { //加载动态链接库d111.dll hinst = loadlibrary("dll1.dll"); if (hinst == nullptr) { cout << "动态链接库加载失败!!!" << endl; freelibrary(hinst); cin.get(); return 0; } //加载导出函数,此处函数名有所不同,需要使用dumpbin.exe进行查询 hello hello = (hello)getprocaddress(hinst, "?hello@@yaxxz"); cout << "hello()="; hello(); cin.get(); //释放动态链接库 freelibrary(hinst); return 0; }
4.查询函数名称的方法
使用dumpbin.exe查询
打开vs的自带的本机工具命令提示
打开之后的界面:
进入dll1.dll所在路径
在控制台中输入dumpbin -exports dll1.dll进行查询
hello函数的函数名为?hello@@yaxxz
5.生成并运行
运行结果
2.创建dll(动态链接库-c方式)
1.创建dll(动态链接库-c方式)
1.创建动态链接库项目,名称为dll2
2.创建dll2.h
输入如下代码
#pragma once #ifdef my_dll_exp #else #define my_dll_exp _declspec(dllimport)////当编译时,头文件不参加编译,所以.cpp文件中先定义,后头文件被包含进来,因此外部使用时,为dllexport,而在内部编译时,则为dllimport #endif //导出函数add extern "c" my_dll_exp double add(double a, double b);
3.创建dll2.cpp(如果有则不需要创建)
输入如下代码:
#include "stdafx.h" #include "dll2.h" //注意以上两个头文件的相对顺序不能改变 #define my_dll_exp _declspec(dllexport) double add(double a, double b) { return a + b; }
4.生成即可。
2.链接dll(动态链接库-c方式)
1.隐式链接
1.准备
dll2.dll(解决方案debug目录下)
dll2.lib(解决方案debug目录下)
2.创建测试项目testdll3
3.把dll2.dll和dll2.lib放入到testdll3项目目录下
4.创建testdll3.cpp
输入如下代码:
//隐式调用 #include <iostream> #pragma comment(lib,"dll2.lib") using namespace std; //载入函数,此处起到头文件的作用 extern "c" _declspec(dllimport) double add(double a, double b); int main() { cout << "add(3,4)=" << add(3, 4) << endl; cin.get(); return 0; }
5.生成并运行
运行结果:
2.显式链接
1.新建测试项目testdll4
2.把dll2.dll放入新建的项目testdll4目录中
3.新建testdll4.cpp
创建dll过程中使用c编译器来编译函数,这样dll文件中的函数名和原dll工程中的函数名就一致了。
墙裂推荐此种方式
输入如下代码:
//显示链接dll-c #include <windows.h>//加载头文件 #include <iostream> using namespace std; //设置全局变量hinst用于存储dll句柄并加载动态链接库 hinstance hinst = nullptr; //声明函数指针 typedef double(*add)(double a,double b); int main() { //加载dll2.dll hinst = loadlibrary("dll2.dll"); if (hinst == nullptr) { cout << "动态链接库加载失败!!!" << endl; freelibrary(hinst); cin.get(); return 0; } //加载函数 add add = (add)getprocaddress(hinst, "add"); cout << "add(3,4)="<<add(3,4)<<endl; cin.get(); freelibrary(hinst); return 0; }
4.生成并运行。