昨日不可追, 今日尤可为.勤奋,炽诚,不忘初心
手机淘宝二维码 扫描
或者打开连接:程序设计开发 ,掌声鼓励,欢迎光临.
C++编译动态库第三方库及使用
为什么很多人,尤其各大厂商只给我们库文件让我们调用,而不直接提供源代码呢?这样的好处是1.把代码封装成各个模块以便复用。 2.省去各种底层调用,省去了大量的代码复制,更符合面向对象编程理念。3.解决了各种同名冲突的问题。4.最重要的,数据无价,隐匿了具体的实现,保护了知识产权。
一.先定个小目标:做个动态库。
1.打开VS2017 文件>新建>项目,如下最后确定:
2.项目>添加类,输入类名Math,确定,如下图
3.Math.h代码如下:
#pragma once
namespace wode
{
double Add(double a, double b);
double Sub(double a, double b);
}
Math.cpp代码如下:
#include "pch.h"
#include "MyMath.h"
double wode::Add(double a, double b)
{
return a + b;
}
double wode::Sub(double a, double b)
{
return a - b;
}
4.我们要把这两个函数做成动态库,那么,我们要添加一个模块(.def)文件:
右击项目名(MathDLL)>添加>新建项,如下所示
输入:
LIBRARY MathDLL
EXPORTS
Add //导出Add函数
Sub //导出Sub函数,同理往下写
*注:不用def模块文件的话,可以zz哎要导出的函数或者类前面加__declspec(dllexport) 一样能导出
5.设置项目生成类型:右击项目名(MathDLL)>常规>配置类型,如图所示
6.生成动态库:确认输出库对应的平台,debug X86,即调试版Win32平台,
右击项目名(MathDLL)>生成。那么在项目目录下,就会生成如下图所示的文件。
这样,我们就把我们具体实现的代码(智慧结晶的)封装到了MathDLL.dll。除非汇编,反编译技术很牛的大拿,不然,没人知道你里面代码是怎么实现。心情不美丽时删库跑路,拿你一点办法都没有。
7.查看动态库。
库是做出来了,可鬼知道里面有没有内容呢,导出正不正确呢,下面就用VS自带的dumpbin.exe来查看库的信息。
在第一上面右击> 打开文件所在位置
Win+R键打开cmd窗口,输入:cd 复制的路径,如图:
按回车,现在就定位到dumpbin.exe所在的文件夹目录了。
如果想要查看MathDLL.dll库中包含哪些函数,可以使用:dumpbin /exports dll的路径语法。
参考博客:VS2010中dumpbin工具的使用:https://blog.csdn.net/fengbingchun/article/details/43956673
那么我这里输入的是dumpbin /exports C:\VSProjs\MathDLL\Debug\MathDLL.dll
全部过程下图所示:
库里面有我们导出的个函数了,成功!
二.写个小程序,测试动态库:
迫不及待,饥渴难耐,赶紧写个程序测试下动态库可不可用。
1.右击解决方案,>添加>新建项目
名称:TestDLL,确定。这样解决方案下面就有两个工程了,右击TestDLL项目,设为启动项目,
2.使用动态库a:
如果人家提供了.h头文件,.lib库文件 .dll动态运行库文件,那么,我们需要在项目,属性中设置包含目录,库目录。具体操作如下:
右击TestDLL项目属性,因为我们要在里面用到我们上面生成的动态库
在包含目录中添加第三方库.h头文件的路径;库目录中添加第三方库.lib文件路径。并且,要将第三方库.dll文件拷贝到exe所在的目录下。
在TestDLL项目的cpp文件中这样写:
//添加动态库头文件
#include "MyMath.h"
//添加.lib库文件
#pragma comment(lib,"MathDLL.lib")
int main()
{
//动态库中的Add函数,在命名空间wode中
std::cout << wode::Add(4.2, 3.1) << std::endl;
//动态库中的Sub函数,在命名空间wode中
std::cout << wode::Sub(4.2, 3.1) << std::endl;
system("pause");
}
运行结果
3.使用动态库b
有些糟老头子坏的很,不给你头文件,.lib库文件,只给你一个.dll动态库,然后让我们去调用dll里面的xx函数,我们该怎么办呢?道友请留步,且听老夫慢慢说来…
在TestDLL项目的cpp文件中这样写:
#include "pch.h"
#include <iostream>
//添加这个头文件
#include"atlstr.h"
int main()
{
//定义函数指针
typedef double(*FUNC)(double, double);
//动态加载dll文件
HMODULE hDLL = LoadLibrary("MathDLL.dll");
if (hDLL != NULL)
{
//直接使用原工程函数名
FUNC Add = FUNC(GetProcAddress(hDLL, TEXT("Add")));
//动态库中的Add函数,在命名空间wode中
std::cout << Add(4.2, 3.1) << std::endl;
//同上Add
FUNC Sub = FUNC(GetProcAddress(hDLL, TEXT("Sub")));
//动态库中的Sub函数,在命名空间wode中
std::cout << Sub(4.2, 3.1) << std::endl;
}
system("pause");
}
报错如下,右击TestDLL项目>属性,在配置属性>常规>字符集>改成 使用多字节字符集
哟嚯嚯嚯,居然绕过了我的命名空间。6