本文只是记载下学习C++动态链接库的过程以及记录学习过程中的一些程序,好开始。

先用VS2010创建一个dll的工程,好,只看图不说话,点击finish就完成创建了。。。

创建头文件developer_dll.h和源代码developer_dll.cpp两个文件,里面可以写你喜欢的函数以及类。

以下是我的.h和.cpp文件代码:

developer_dll.h:

#pragma once
#ifdef dev_dll_api
#else
#define dev_dll_api _declspec(dllimport)
#endifnamespace developer_dll_namespace
{dev_dll_api void add(int a, int b);dev_dll_api void subtract(int a, int b);class dev_dll_api developer_dll_class{public:void class_add(int a, int b);void class_subtract(int a, int b);protected:private:int x;int y;};
}

developer_dll.cpp:

#include <iostream>#define dev_dll_api _declspec(dllexport)
#include "developer_dll.h"namespace developer_dll_namespace
{void add(int a, int b){std::cout<<"两者之和(调用普通函数):"<<a+b<<std::endl;}void subtract(int a, int b){std::cout<<"两者之差(调用普通函数):"<<((a>b)?(a-b):(b-a))<<std::endl;}void developer_dll_class::class_add(int a, int b){std::cout<<"两者之和(调用类的成员函数):"<<a+b<<std::endl;}void developer_dll_class::class_subtract(int a, int b){x = a;y = b;std::cout<<"两者之差(调用类的成员函数):"<<((x>y)?(x-y):(x-y))<<std::endl;}
}

好,搞定这两个就可以build生成.lib以及.dll文件了,看图:

然后就可以创建使用者的.h文件和.cpp文件来加载dll,在程序中加载DLL有两种方法,分别为隐式链接和动态加载dll隐式链接需要(.lib、.dll、.h)文件,动态加载dll只需(.dll)文件就可以了。

1、然后下面先以隐式链接测试:

创建源代码user_dll.cpp来测试dll。

.lib、.dll、.h)文件复制进来并且创建相应的文件夹。


在这里将lib的路径加进去,不然编译链接会出错。

下面是我的user_dll.cpp:

#include <iostream>
#include <Windows.h>#include "developer_dllh/developer_dll.h"
#pragma comment(lib, "developer_dll.lib") using namespace std;
using namespace developer_dll_namespace;int main()
{add(2,3);subtract(2,3);developer_dll_class users;users.class_add(2,3);users.class_subtract(2,3);system("pause");return 0;
}

运行测试一把:我的结果是这样的:

那如果我们只想导出类的部分函数要怎么导出:

这里我们可以利用depends这个软件来查看dll导出了哪些函数:

这里为什么函数名会是这样子呢,主要是C++为了实现重载实现了函数倾轧,函数名就按照一定的规则发生的变化,只要都是C++是可以正常调用的。如果要用C语言调用dll,就要添加extern “C”,但是它不能用于导出类的成员函数。如果是给其他语言调用则使用extern “C”也没有卵用。要避免这个问题就得使用模块定义文件.def,待会就测试这个怎么使用。

 add(2,3);subtract(2,3);developer_dll_class users;users.class_add(2,3);//users.class_subtract(2,3); 这个成员函数没有导出,所以不能用了。system("pause");return 0;

好我们测试一把:

2、好下面来实现动态链接dll:

这里需要用到几个函数:

LoadLibrary:

[格式]:

  1. function LoadLibrary(LibFileName : PChar): Thandle;

[说明]:参数 LibFileName 指定了要装载的 DLL 文件名,如果 LibFileName 没有包含一个路径,系统将按照:当前目录、Windows 目录、Windows 系统目录、包含当前任务可执行文件的目录、列在 PATH 环境变量中的目录等顺序查找文件。

[功能]:加载由参数 LibFileName 指定的 DLL 文件。

如果函数操作成功,将返回装载 DLL 库模块的实例句柄,否则,将返回一个错误代码。假如在应用程序中用 LoadLibrary 函数装入某一个 DLL 前, 其他应用程序已把该 DLL 装入内存中了,则系统将不再装入该 DLL 的另一个实例,而是使该 DLL 的“引用计数”加 1 。

GetProAccess

[格式]:

  1. function GetProcAddress(Module:Thandle; ProcName:PChar): TfarProc;

[说明]:参数 Module 包含被调用函数的 DLL 句柄,这个值由 LoadLibrary 返回, ProcName是指向含有函数名的以 nil 结尾的字符串指针,或者可以是函数的次序值,但大多数情况下,用函数名是一种更稳妥的选择。这里如果要使用函数名字如果不采用.def的方式会比较麻烦。

int main()
{HMODULE load_ex = LoadLibrary(_T("developer_dll.dll"));//返回一个句柄if (load_ex){addprt add = (addprt)GetProcAddress(load_ex,"?add@developer_dll_namespace@@YAXHH@Z");if (add){add(2,3);}subtractprt subtract = (subtractprt)GetProcAddress(load_ex,"?subtract@developer_dll_namespace@@YAXHH@Z");if (subtract){subtract(2,3);}}

如果该函数执行成功,则返回 DLL 中由参数 ProcName 指定的过程或函数的入口地址,否则返回 nil 。
FreeLibrary:

[功能]:返回参数 Module 指定的模块中,由参数 ProcName 指定的过程或函数的入口地址。

[格式]:

  1. procedure  FreeLibrary(Module: Thandle);

[说明]:将由参数 Module 指定的 DLL 文件从内存中卸载 1 次。
[说明]:Module 为 DLL 库的句柄。这个值由 LoadLibrary 返回。由于 DLL 在内存中只装载一次,因此调用 FreeLibrary 首先使 DLL 的引用计数减 1,如果计数减为 0 则卸载该 DLL。

上面函数说明是从这里摘下来的,感兴趣可以去阅读https://www.cnblogs.com/westsoft/p/5936092.html

现在测试以导出文件(.def)的方式导出dll,在工程里面添加.def文件。

下面是我的源文件:

//.cpp文件
#include <iostream>
#include "developer_dllmd.h"
namespace developer_dll_namespace
{void add(int a, int b){std::cout<<"两者之和(调用普通函数):"<<a+b<<std::endl;}void subtract(int a, int b){std::cout<<"两者之差(调用普通函数):"<<((a>b)?(a-b):(b-a))<<std::endl;}
#if 0
void developer_dll_class::class_add(int a, int b){std::cout<<"两者之和(调用类的成员函数):"<<a+b<<std::endl;}void developer_dll_class::class_subtract(int a, int b){x = a;y = b;std::cout<<"两者之差(调用类的成员函数):"<<((x>y)?(x-y):(y-x))<<std::endl;}
#endif
}
//.h文件
#pragma  once
namespace developer_dll_namespace
{void add(int a, int b);void subtract(int a, int b);#if 0
class developer_dll_class{public:void class_add(int a, int b);void class_subtract(int a, int b);protected:private:int x;int y;};
#endif
}
//.def文件
LIBRARY "developer_dllmd"
EXPORTS
add @1
export_subtract=subtract @2

下面编写user函数实现动态调用:

#include <iostream>
#include <Windows.h>
#include <tchar.h>
#include <winuser.h>using namespace std;
typedef void (*addprt)(int a, int b);
typedef void (*subtractprt)(int a, int b);int main()
{HMODULE load_ex = LoadLibraryA("developer_dllmd.dll");//返回一个句柄if (load_ex){addprt add = (addprt)GetProcAddress(load_ex,"add");if (add){add(2,3);}addprt add1 = (addprt)GetProcAddress(load_ex,MAKEINTRESOURCEA(1));if (add1){cout<<"通过序号调用:"<<"\t";add1(2,3);}else{cout<<"获取地址失败"<<endl;}subtractprt subtract = (subtractprt)GetProcAddress(load_ex,"export_subtract");if (subtract){subtract(2,3);}subtractprt subtract1 = (subtractprt)GetProcAddress(load_ex,MAKEINTRESOURCEA(2));if (subtract1){cout<<"通过序号调用:"<<"\t";subtract1(2,3);}}
        FreeLibrary(load_ex);
   system("pause");return 0;
}

好测试一把,我们看下结果如何:

对于类的动态导出其实文中方法不太好,还有更好的方法下会解说。

好,文章到此结束,谢谢观看,欢迎提问,共同讨论和提高。

VS2010 学习C++动态链接库的创建与使用(带实例代码)相关推荐

  1. php django mysql配置文件_Mysql学习Django+mysql配置与简单操作数据库实例代码

    <Mysql学习Django+mysql配置与简单操作数据库实例代码>要点: 本文介绍了Mysql学习Django+mysql配置与简单操作数据库实例代码,希望对您有用.如果有疑问,可以联 ...

  2. vs2010 学习Silverlight学习笔记(8):使用用户控件

    概要: 这个类似于封装控件样式.不过封装的是整个或是多个控件罢了,然后用的时候就可以直接引用过来了. 创建用户控: 这个也很简单,不过有几个地方需要注意下.这个就不照抄了,咱们也自己写一个. 步骤: ...

  3. 学习在Unity中创建一个动作RPG游戏

    游戏开发变得简单.使用Unity学习C#并创建您自己的动作角色扮演游戏! 你会学到什么 学习C#,一种现代通用的编程语言. 了解Unity中2D发展的能力. 发展强大的和可移植的解决问题的技能. 了解 ...

  4. LINUX动态链接库的创建与使用

    大家都知道,在 WINDOWS系统中有很多的动态链接库(以.DLL为后缀的文件,DLL即Dynamic Link Library).这种动态链接库,和静态函数库不同,它里面的函数并不是执行程序本身的一 ...

  5. vs2010 学习Silverlight学习笔记(7):控件样式与模板

    概要: 终于知道Silverlight--App.xaml是干什么用的了,不仅可以用来封装样式(类似css),还可以制定控件模版...好强大的功能啊. 封装: 继续学习<一步一步学Silverl ...

  6. Unity插件之NGUI学习(4)—— 创建UI2DSprite动画

    创建一个新的Scene.并按 Unity插件之NGUI学习(2)创建UI Root,并在UI Root的Camera下创建一个Panel. 然后在选中Panel,在菜单中选择NGUI->Crea ...

  7. 《LINUX下动态链接库的创建与应用》

    大家都知道,在windows系统中有很多的动态链接库(以.dll为后缀的文档,dll即dynamic link library).这种动态链接库,和静态函数库不同,他里面的函数并不是执行程式本身的一部 ...

  8. linux 动态链接库的创建和使用--动态连接

    linux 动态链接库的创建和使用--动态连接 分类: C 编程 2012-03-25 17:01 568人阅读 评论(0) 收藏 举报 linuxreferencefunctiondatec /* ...

  9. LINUX系统中动态链接库的创建与使用

    大家都知道,在WINDOWS系统中有很多的动态链接库(以.DLL为后缀 的文件,DLL即Dynamic Link Library).这种动态链接库,和静态函数库不 同,它里面的函数并不是执行程序本身的 ...

最新文章

  1. Fedora 30用dnf安装OpenCV及g++编译其应用程序
  2. 科大星云诗社动态20210303
  3. 如何节省1T图片带宽?解密极致图像压缩!
  4. 写给深圳首期Python自动化开发周未班的信
  5. Oracle 学习笔记(三)
  6. 如何使用 SSH 控制连接 Windows 服务器
  7. java逻辑量_java – 增量逻辑
  8. cocos2dx3.2文件结构和代码结构
  9. [Java] 蓝桥杯ALGO-30 算法训练 入学考试
  10. 阻止具有特定文件扩展名的附件的电子邮件
  11. python游戏编程之环境配置
  12. Windows server2012R2 企业内部搭建虚拟专用网络服务
  13. Zend与PHP之间到底是什么关系
  14. 软考 2015 年上半年 网络管理员 上午试卷
  15. 十年MFC经历认识的Microsoft技术
  16. android播放器概述,【Android】 从头搭建视频播放器(1)——概述
  17. 奇迹s12源码_奇迹S12-2更新内容
  18. 遗传算法的c++语言程,遗传算法 C++的程序
  19. 《Java程序性能优化》-笔记
  20. Spring mvc 的生命周期

热门文章

  1. buuctf ciscn_2019_sw_5
  2. dwg在坐标转换的注意事项
  3. 科技版“传音入密”:音频聚光灯现在怎么样了?
  4. 网站能正常登陆但是点进去出现404错误_404页面怎么破?诠网科技给你正确的解决方法...
  5. 中国会率先实现Amazon GO模式
  6. 利用旧电脑去搭建linux服务器
  7. 数据分析平台页面设计_平台设计剖析
  8. 【QT开发笔记-基础篇】| 第五章 绘图QPainter | 5.12 文本、图片
  9. 身份证号,手机号校验
  10. python中调用API的几种方式