动态链接库的使用有两种方式,一种是显式调用,一种是隐式调用

动 态 链 接 库 的 使 用 有 两 种 方 式 , 一 种 是 显 式 调 用 , 一 种 是 隐 式 调 用 动态链接库的使用有两种方式,一种是显式调用,一种是隐式调用 使


显式调用:使用LoadLibrary载入动态链接库、使用GetProcAddress获取某函数地址

隐式调用:可以使用#pragma comment(lib, “XX.lib”)的方式,也可以直接将XX.lib加入到工程中

实例

// dllUser.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "wuygDll.h"
#include <iostream>
#include <windows.h>

#pragma comment(lib, "wuygDll")

int _tmain(int argc, _TCHAR* argv[])
{
	//隐式调用
	wuygFun();
	
	//显式调用
	typedef int (__stdcall *Fun)(void); 
	HMODULE hDll = ::LoadLibrary(L"wuygDll");
	Fun TestFun = ::GetProcAddress(hDll, "wuygFun");
	TestFun();
	system("pause");
	return 0;
}



D L L 的 编 写 DLL的编写 DLL

编写dll的时候,需要函数重命名

解决方式有两种:

  • 直接在代码里解决采用
extent”c”
_declspec(dllexport)
#pragma comment(linker, "/export:[Exports Name]=[Mangling Name]")
  • 采用def文件

编写dll时,为什么有 extern “C”

还不是C++不通用呗,例如:Borland C++跟Mircrosoft C++就不同

任何一个支持c语言的编译器,它编译出来的obj文件可以共享,链接成可执行文件。这是一种标准,如果DLL跟其使用者都采用这种约定,那么就可以解决函数重命名规则不一致导致的错误。

注意到extern “C”的作用是为了解决函数符号名的问题,这对于动态链接库的制造者和动态链接库的使用者都需要遵守的规则。


_declspec(dllexport)和_declspec(dllimport)的作用


_declspec(dllexport)用在dll上,用于说明这是导出的函数。

_declspec(dllimport)用在调用dll的程序中,用于说明这是从dll中导入的函数


因为dll中必须说明函数要用于导出,所以_declspec(dllexport)很有必要。

但是也可以使用def文件来说明哪些函数用于导出,同时def文件里边还有函数的编号。

使用_declspec(dllimport)却不是必须的,但是建议这么做。因为如果不用_declspec(dllimport)来说明该函数是从dll导入的,那么编译器就不知道这个函数到底在哪里,生成的exe里会有一个call XX的指令,这个XX是一个常数地址,XX地址处是一个jmp dword ptr[XXXX]的指令,跳转到该函数的函数体处,显然这样就无缘无故多了一次中间的跳转。如果使用了_declspec(dllimport)来说明,那么就直接产生call dword ptr[XXX],这样就不会有多余的跳转了。


__stdcall的作用

这是一种函数的调用方式。

默认情况下VC使用的是__cdecl的函数调用方式,如果产生的dll只会给C/C++程序使用,那么就没必要定义为__stdcall调用方式,如果要给Win32汇编使用(或者其他的__stdcall调用方式的程序),那么就可以使用__stdcall。

*.def文件

指定导出函数,并告知编译器不要以修饰后的函数名作为导出函数名,而以指定的函数名导出函数(比如有函数func,让编译器处理后函数名仍为func)。这样,就可以避免由于microsoft VC++编译器的独特处理方式而引起的链接错误。

即,使用了def文件,那就不需要extern “C”了,也可以不需要__declspec(dllexport)了

(不过,dll的制造者除了提供dll之外,还要提供头文件,需要在头文件里加上这extern”C”和调用约定,因为使用者需要跟制造者遵守同样的规则,除非使用者和制造者使用的是同样的编译器并对调用约定无特殊要求)

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一、 课程设计目的 学会用C++语言和数据结构知识实现表达式的解析与计算;学会使用动态链接库技术进行编程;学会编辑、编译、运行MFC应用程序的基本过程.学会MFC可视化编程技术。 二、 课程设计内容与实现的功能 1.C++语言的顺序结构,分支结构,循环结构,函数,结构体,指针,MFC可视化编程技术。 2.数据结构中的二叉树数据组织、存贮、后序遍历及其操作。 3. 使用动态链接库进行函数模块的设计,实现计算功能。 4.编程中使用了动态连接库技术; 能实现表达式的输入,解析与计算 三、 系统分析与设计 1、系统分析 应用程序使用DLL可以采用两种方式一种隐式链接,另一种显式链接。在使用DLL之前首先要知道DLL中函数的结构信息。Visual C++6.0在VC in目录下提供了一个名为Dumpbin.exe的小程序,用它可以查看DLL文件中的函数结构。另外,Windows系统将遵循下面的搜索顺序来定位DLL: 1.包含EXE文件的目录,2.进程的当前工作目录, 3.Windows系统目录, 4.Windows目录,5.列在Path环境变量中的一系列目录。 1.隐式链接 隐式链接就是在程序开始执行时就将DLL文件加载到应用程序当中。实现隐式链接很容易,只要将导入函数关键字_declspec(dllimport)函数名等写到应用程序相应的头文件中就可以了 2.显式链接 显式链接是应用程序在执行过程中随时可以加载DLL文件,也可以随时卸载DLL文件,这是隐式链接所无法作到的,所以显式链接具有更好的灵活性,对于解释性语言更为合适。不过实现显式链接要麻烦一些。在应用程序中用 LoadLibrary或MFC提供的AfxLoadLibrary显式的将自己所做的动态链接库调进来,动态链接库的文件名即是上述两个函数的参数,此后再用GetProcAddress()获取想要引入的函数。自此,你就可以象使用如同在应用程序自定义的函数一样来调用此引入函数了。在应用程序退出之前,应该用FreeLibrary或MFC提供的AfxFreeLibrary释放动态链接库。 2、系统设计: 按照系统设计要求,用Visual C++设计和开发一个MFC应用程序---高级计算器。计算器的界面设计、计算功能实现、算式计算和动态链接库使用等。提交由需求分析:系统设计说明、系统技术文档、系统使用说明书和源程序代码为附录构成的实验报告。 2.1、模块设计: 1. 计算器界面 计算器界面包括主题“高级计算器”和背景图片以及电子日历。在计算区上有显示文本框和数字按钮以及运算符按钮。在计算区上部分有运算模式选择模块和小提示语句。 2. 模块功能简介 系统分为多个模块,分别为计算模块、错误分析模块、界面显示模块和模式选择模块。其中计算模块用来进行各种基本的加、减、乘、除的运算并且显示运算结果;错误分析模块用来进行错误处理;界面显示模块用来美化计算器界面;模式选择模块用来进行运算模式的选择和切换,以实现不同的运算要求

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值