VC++ DLL 3 动态链接库
前面先介绍了静态链接库的方式提供了函数结构的方法,现在就来说下,如果用非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的程序需要修改调用方式:
其中,语句含义如下:
#pragma comment(lib, "noMFCdllSrc.lib") //同前面静态链接库的链接方式一样
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 动态链接库的更多相关文章
- VC++DLL动态链接库程序
VC++DLL动态链接库程序 VC++DLL动态链接库程序 C++ DLL 导出函数 使用VS2017等IDE生成dll程序,示例如下: C++ DLL 导出类 1.导出类中第一种方法:简单导出类(不 ...
- Qt调用VC++生成的动态链接库
Qt如何调用VC++生成的动态链接库?假设当前有VC++编译器生成的动态库文件testdll.h,testdll.lib和testdll.dll. testdll.h文件源码如下: #ifdef TE ...
- Qt不同版本编译器,调用VC++生成的动态链接库
今天用QT编译生成的共享库自己却怎么都不能调用,查了N久后找到这个帖子,发现搞定了,记录一下 http://qiusuoge.com/12720.html Qt如何调用VC++生成的动态链接库?假设当 ...
- VC++ DLL 发布到生产环境过程
最近项目中用到了VC++ DLL,在本机调试时无任何问题,但是发布出来后,COPY到另外的机器就报错,说找不到DLL,由于自身工作接触这方面比较少,经过一番折腾后,终于解决,以下为解决步骤 一,平台工 ...
- C# 与 VC Dll 传输信息
考虑: 使用string类型传送: 在VC Dll中解析字符: 使用 string 类型将解析的类型传送到C#程序中: 建立VC解析的函数,提高代码可重用性
- C#调用VC dll输出参数
最近做项目需要把以前Vc写的程序整合到VS2005来,用c#写的,以前VC的动态连接库写好了,重写比较麻烦,让C#调用VC dll就好了.但碰到了一个问题:VC中作为输出参数的char*类型的变量应该 ...
- 重要:VC DLL编程
VC DLL编程 静态链接:每个应用程序使用函数库,必须拥有一份库的备份.多个应用程序运行时,内存中就有多份函数库代码的备份. 动态连接库:多个应用程序可以共享一份函数库的备份. DLL的调用方式:即 ...
- Python的扩展接口[2] -> 动态链接库DLL[0] -> 动态链接库及辅助工具
动态链接库 / Dynamic Link Library 目录 动态链接库简介 函数封装DLL 组件对象模型COM 如何判断.dll文件是COM还是DLL 辅助工具 1 动态链接库简介 / DLL I ...
- 丢失libiconv-2.dll解决办法以及无法定位输入点libiconv-2.dll到动态链接库
摘自https://blog.csdn.net/mengxiangjia_linxi/article/details/78147348 丢失libiconv-2.dll解决办法以及无法定位输入点lib ...
随机推荐
- WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! 的解决办法
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ WARNING: REMOTE HOST IDENTIFICATION HAS ...
- phpstrom+win10拼音输入法不跟随情况
PHPSTORM拼中文时悬浮框一直在右下角,真是逼死强迫症的操作! 最好解决方案: 下载讯飞输入法,虽然有点不习惯,用着用着就行了 等待官方修复着bug吧; 网上说的直接下载jre64覆盖原来的版本也 ...
- java 接口 2.19
接口中所有的方法都是抽象的和public的,所有的属性都是public,static,final的.
- Scala 线性化规则和 super 操作
如果一个类有多个父类,且父类的有相同的函数 f,在子类和父类中调用 super.f 都是按从右到左的调用函数的顺序. 这个规则名为:Linearization Rules 如下的代码 trait Ba ...
- 数据结构——java Queue类
定义 队列是一种特殊的线性表,它只允许在表的前端进行删除操作,而在表的后端进行插入操作. LinkedList类实现了Queue接口,因此我们可以把LinkedList当成Queue来用 图例 Que ...
- SwiftUI中多设备运行方法
https://blog.csdn.net/weixin_42679753/article/details/94465674 https://www.jianshu.com/p/17fc7929fcb ...
- Linux系统sda变sdb的解决
起因 我的电脑有一个128G的固态以及一个500G的机械,我将系统安装在128G固态中,于是将500G的机械(/dev/sdb)挂在在/home目录下,安装完系统后执行lsblk命令 NAME MAJ ...
- POJ 1472:Instant Complexity 模拟时间复杂度
Instant Complexity Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 1908 Accepted: 658 ...
- Exchange Server 2010邮件策略与遵从性
本文档附带了一个附档,里面详细的描述了如何在Exchange Server 2010中配置如下内容: 1.邮件分类 2.免责申明 3.配置信息隔离墙 4.邮件审核 5.Exchange 2010与AD ...
- XV6操作系统代码阅读心得(五):文件系统
Unix文件系统 当今的Unix文件系统(Unix File System, UFS)起源于Berkeley Fast File System.和所有的文件系统一样,Unix文件系统是以块(Block ...