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 ...
随机推荐
- 微信小程序IOS真机调试发生了SSL 错误,无法建立与该服务器的安全连接
小程序 真机调试 IOS request:fail 发生了SSL 错误,无法建立与该服务器的安全连接,解决方法服务器中打开Powerhell,执行以下代码,然后重启服务器 # Enables TLS ...
- 011、MySQL取14天前Unix时间戳
#取14天前时间戳 SELECT unix_timestamp( DATE_SUB( curdate( ), INTERVAL DAY ) ); 效果如下: 不忘初心,如果您认为这篇文章有价值,认同作 ...
- java项目构建工具Maven
一.java-maven常用命令 mvn archetype:create 创建Maven项目 mvn compile 编译源代码 mvn deploy 发布项目 mvn test-compile 编 ...
- 调用dos
两个方法 function RunDosCommand(Command: string): string; var hReadPipe: THandle; hWritePipe: THandle; S ...
- delphi http请求用到的编码方式
uses HttpEncode: HttpEncode(AnsiToUtf8('***'))
- java集合简单特性
- Spring Aop 原理分析
@EnableAspectJAutoProxy Aop功能开启注解 为容器中导入 @Import(AspectJAutoProxyRegistrar.class)组件,在其重写方法中为 ioc容器 注 ...
- android 动画基础绘——view 动画(二)[补]
前言 这个是对view 动画的补充,是一些view 动画的特殊使用场景. 回顾第一篇关于view 动画的,我介绍到view的动画都是针对元素本身的. 当我们开发view动画的时候,我们看到几个元素在做 ...
- RabbitMQ整合Spring Booot【消费者补偿幂等问题】
如果消费者 运行时候 报错了 package com.toov5.msg.SMS; import org.springframework.amqp.rabbit.annotation.RabbitHa ...
- Block循环引用问题(Objective-c)
造成循环引用的简单理解是:Block的拥有者在Block作用域内部又引用了自己,因此导致了Block的拥有者永远无法释放内存,就出现了循环引用的内存泄漏 示例代码 @interface ObjTest ...