前面先介绍了静态链接库的方式提供了函数结构的方法,现在就来说下,如果用非MFC的动态链接库要怎么实现,这个过程稍微复杂一点点,但是基本也都是一个套路下来。

1、新建一个工程:

2、编写cpp文件和头文件,这里有两种方式:

(1)、新建工程之后会有相应的cpp文件,可以直接在cpp文件中编写:

(2)、新建新的.h/.cpp文件进行编写:

3、编译生成lib文件和dll文件:

4、新建调用工程:

这里要注意几点:

(1)、typedef int(*lpAddFun)(int, int);宏定义函数指针类型,该定义是与将要调用函数的形式一样的,也就是输入参数和返回值都要一样,函数名称可以不同;

(2)、hDll = LoadLibrary(L"noMFCdllSrc.dll");是加载dll文件进来,一定要注意L"noMFCdllSrc.dll"前面有个大写的L,不加这个的话会报错,涉及到const char*跟LP LPCWSTR数据类型的转换问题,函数返回值的类型如下:

(3)、addFun = (lpAddFun)GetProcAddress(hDll, "add");获取函数add在dll文件中的地址;

(4)、使用完函数之后记得调用FreeLibrary来释放内存;

(5)、使用dll只需要将相关的dll文件放置在工程调用到的位置即可,不需要将.h文件和.lib文件一起拷贝过来;

(6)、如果需要在调用的工程中进入函数调试的话,暂时不知道;

(7)、DLL内的函数分为内部函数和外部函数,内部函数是无法通过调用dll来给外部使用,只能是dll内部使用,因此,要提供给外部使用的话,需要在函数声明处添加__declspec(dllexport),前面是两个下划线,即可声明为导出函数。

5、声明DLL的另一种方式是采用模块定义(.def)文件声明,.def文件为连接器提供了关于被链接程序的导出、属性和其他方面的信息,需要在dll工程中添加.def文件:

(1)、声明def文件:

def文件规则:

a、LIBRARY语句声明了.def文件对应的dll文件;

b、EXPORT语句后面跟随的是导出函数名,导出函数名后面的@数字表示导出函数的序号,在调用函数的时候可以用;

c、def文件中的注释由每个注释行开始处的分号指定,并且注释不可以和代码语句同一行。

(2)、调用,通过def文件定义后,要调用dll的方式跟基本前面一样的但是在获取函数地址的时候要通过下面这种方式来获取:

这一步我应该是没有尝试的,后面有尝试的话再来更新。

6、DLL的调用分为动态调用和静态调用:

(1)、动态调用,前面的方式都属于动态调用,就是三个步骤:“LoadLibrary-GetProcAddress-FreeLibrary”;

(2)、静态调用:编译系统完成对dll的加载,应用程序结束完成对DLL的卸载,也就是说调用dll的应用程序的数量系统中有记录,每结束一个计数减一直到调用dll的所有应用程序都结束了,才释放。静态调用需要将dll文件和lib文件一起使用不需要修改编写dll的程序,只是调用dll的程序需要修改调用方式:

其中,语句含义如下:

  1. #pragma comment(lib, "noMFCdllSrc.lib") //同前面静态链接库的链接方式一样
  2. extern "C" int __declspec(dllimport)add(int, int); //则是声明导入函数;

静态调用的过程:在工程中导入lib文件,在应用程序中,lib文件将作为DLL的替代文件参与编译;然后声明导入函数,调用。

7、dll函数的入口DLLMain函数

提供dll的时候并没有提供DllMain函数,系统会引入一个不做任何操作的缺省DllMain函数,但是在编写dll的时候,DllMain还是必须的;DllMain不能被引用,只能被系统加载和卸载dll、单个线程启动或者终止的时候自动调用;

函数输入:

APIENTRY是宏定义#define APIENTRY WINAPI

而WINAPI则是宏定义#define WINAPIV __cdecl,这表示函数以标准Pascal的方式调用

win32中,HMODULE的值和HINSTANCE一样,进程中每个dll模块都被全局唯一的32字节的HINSTANCE句柄标识,只有在特定的进程内部有效,并且,这个HINSTANCE代表了dll模块在进程虚拟空间中的起始位置。

8、__stdcall声明

VC++编写的程序要被其他语言调用,必须将函数的调用方式声明为__stdcall,WINAPI都采用这种方式;但是C/C++默认是__cdecl,这两种方式生成的符号不同:采用C编译的时候,__stdcall调用约定在函数名前加下划线,后加@数字,如”_add@1”;但是,__cdecl声明的只在前面加下划线,如”_add”;

所以,如果在dll中声明为int __stdcall add(int x, int y);的话,在调用的时候就要声明为typedef int(__stdcall *lpAddFun)(int, int);否则会报错。

大概就写到这里,这里还有导出变量和类的做法,还没有尝试,就先不写了,后面有尝试的话会补上的。

春风动春心,流目瞩山林。

山林多奇采,阳鸟吐清音。

  -- 佚名 《子夜四时歌·春风动春心》

VC++ DLL 3 动态链接库的更多相关文章

  1. VC++DLL动态链接库程序

    VC++DLL动态链接库程序 VC++DLL动态链接库程序 C++ DLL 导出函数 使用VS2017等IDE生成dll程序,示例如下: C++ DLL 导出类 1.导出类中第一种方法:简单导出类(不 ...

  2. Qt调用VC++生成的动态链接库

    Qt如何调用VC++生成的动态链接库?假设当前有VC++编译器生成的动态库文件testdll.h,testdll.lib和testdll.dll. testdll.h文件源码如下: #ifdef TE ...

  3. Qt不同版本编译器,调用VC++生成的动态链接库

    今天用QT编译生成的共享库自己却怎么都不能调用,查了N久后找到这个帖子,发现搞定了,记录一下 http://qiusuoge.com/12720.html Qt如何调用VC++生成的动态链接库?假设当 ...

  4. VC++ DLL 发布到生产环境过程

    最近项目中用到了VC++ DLL,在本机调试时无任何问题,但是发布出来后,COPY到另外的机器就报错,说找不到DLL,由于自身工作接触这方面比较少,经过一番折腾后,终于解决,以下为解决步骤 一,平台工 ...

  5. C# 与 VC Dll 传输信息

    考虑: 使用string类型传送: 在VC Dll中解析字符: 使用 string 类型将解析的类型传送到C#程序中: 建立VC解析的函数,提高代码可重用性

  6. C#调用VC dll输出参数

    最近做项目需要把以前Vc写的程序整合到VS2005来,用c#写的,以前VC的动态连接库写好了,重写比较麻烦,让C#调用VC dll就好了.但碰到了一个问题:VC中作为输出参数的char*类型的变量应该 ...

  7. 重要:VC DLL编程

    VC DLL编程 静态链接:每个应用程序使用函数库,必须拥有一份库的备份.多个应用程序运行时,内存中就有多份函数库代码的备份. 动态连接库:多个应用程序可以共享一份函数库的备份. DLL的调用方式:即 ...

  8. Python的扩展接口[2] -> 动态链接库DLL[0] -> 动态链接库及辅助工具

    动态链接库 / Dynamic Link Library 目录 动态链接库简介 函数封装DLL 组件对象模型COM 如何判断.dll文件是COM还是DLL 辅助工具 1 动态链接库简介 / DLL I ...

  9. 丢失libiconv-2.dll解决办法以及无法定位输入点libiconv-2.dll到动态链接库

    摘自https://blog.csdn.net/mengxiangjia_linxi/article/details/78147348 丢失libiconv-2.dll解决办法以及无法定位输入点lib ...

随机推荐

  1. Linux基础命令、软件安装

    常用命令 查看当前系统中存在哪些shell cat /etc/shells [root@** ~]# cat /etc/shells /bin/sh /bin/bash /usr/bin/sh /us ...

  2. BFC的基础理解及应用场景

    最近学习了BFC,开始学习的时候,单纯看概念,有种云里雾里的感觉,字都认识,凑一起啥意思大致也知道,但是具体有什么用呢? 这个就有点迷迷糊糊的,经过老师的讲解,以及自己课后的代码实验与总结,就拨云见日 ...

  3. JSON数组序列化C#方法

    /// <summary> /// dataTable转换成Json格式 JSON对应关系 三层数组 /// </summary> /// <param name=&qu ...

  4. use matplotlib to drew a table

    $sudo apt-get install python3-matplotlib gyf@gyf-VirtualBox:~$ python3Python 3.6.9 (default, Nov  7 ...

  5. C++面试常见问题——06数组排序

    数组排序 冒泡.最简单的冒泡,没啥好讲的 #include<iostream> using namespace std; void BubbleSort(int a[],int len){ ...

  6. C++编程学习(九)this指针&友元函数

    mooc西工大魏英老师的课程通道关闭了,难受.现在边看工程代码边重温刷第一遍C++时候的知识点,顺序没有按照大纲的来,想到哪写到哪. this是干啥用的? 简介:在 C++ 中,每一个对象都能通过 t ...

  7. 让vscode使用Pipenv工作环境

    1.查看Pipenv的位置 # 先激活Pipenv环境 pipenv shell # 获取当前虚拟环境的位置 pipenv --venv 2.打开setting.json配置文件 Ctrl+Shift ...

  8. 048-PHP定义常量

    <?php define('NUM',123); //定义常量NUM echo NUM; //输出NUM的值 define('STR','ABC',TRUE); //定义常量STR并设置大小写不 ...

  9. 018-PHP判断文件是否存在

    <?php print("data.txt文件是否存在?" . "<br>"); if (file_exists("data.txt ...

  10. 八、React实战:可交互待办事务表(表单使用、数据的本地缓存local srtorage、生命同期函数(页面加载就会执行函数名固定为componentDidMount()))

    一.项目功能概述 示例网址:http://www.todolist.cn/ 功能: 输入待做事项,回车,把任务添加到 [正在进行] [正在进行] 任务,勾选之后,变成已[经完成事项] [已完成事务], ...