DLL的链接方式分为两种:隐式链接和显式链接

DLL导出的函数 和 导出类在调用时,有些区别,这里暂时不讲,直说简单的导出函数;

隐式链接:

  1. #include "stdafx.h"
  2. #include "MathDLL.h"
  3. #pragma comment(lib, "MathDLL.lib") //你也可以在项目属性中设置库的链接
  4. int main()
  5. {
  6. Add(1,2);
  1. return(1);

显式链接:

在头文件或是包含头文件下面添加函数指针,函数里面两个int类型参数,函数返回值是int类型,如下:

typedef int (*DLLFunc)(int,int);

  1. DLLFunc pAdd;
  2. HINSTANCE h_Instance = LoadLibrary(_T("MathDLL.dll"));
  3. if(h_Instance == NULL)
  4. {
  5. FreeLibrary(h_Instance);
  6. }
  7. pAdd = (DLLFunc)GetProcAddress(h_Instance,("Add"));
  8. if(pAdd == NULL)
  9. {
  10. FreeLibrary(h_Instance);
  11. }
  12. int c = pAdd(5,9);
  13. CString str;
  14. str.Format(_T("输出加法数字是:%d"),c);
  15. MessageBox(str,_T("加法算法"));
  16. FreeLibrary(h_Instance);

我这里测试时创建的MFC的对话框程序,所以不需要包含特殊头文件,如果不是的话,考虑要包含#include "windows.h",同时显式链接不需要包含dll的头文件,

下面是对dll一些解释,这是我从别的文章拿过来的!

一个HINSTANCE是一个Windows数据类型:是一个实例的句柄;在此情况下,这个实例将是这个DLL。你可以通过使用函数LoadLibrary()获得DLL的实例,它获得一个名称作为参数。在调用LoadLibrary函数后,你必需查看一下函数返回是否成功。你可以通过检查HINSTANCE是否等于NULL(在Windows.h中定义为0或Windows.h包含的一个头文件)来查看其是否成功。如果其等于NULL,该句柄将是无效的,并且你必需释放这个库。换句话说,你必需释放DLL获得的内存。如果函数返回成功,你的HINSTANCE就包含了指向DLL的句柄。

一旦你获得了指向DLL的句柄,你现在可以从DLL中重新获得函数。为了这样作,你必须使用函数GetProcAddress(),它将DLL的句柄(你可以使用HINSTANCE)和函数的名称作为参数。你可以让函数指针获得由GetProcAddress()返回的值,同时你必需将GetProcAddress()转换为那个函数定义的函数指针。举个例子,对于Add()函数,你必需将GetProcAddress()转换为AddFunc;这就是它知道参数及返回值的原因。现在,最好先确定函数指针是否等于NULL以及它们拥有DLL的函数。这只是一个简单的if语句;如果其中一个等于NULL,你必需如前所述释放库。

一旦函数指针拥有DLL的函数,你现在就可以使用它们了,但是这里有一个需要注意的地方:你不能使用函数的实际名称;你必需使用函数指针来调用它们。在那以后,所有你需要做的是释放库如此而已。

模块句柄

进程中的每个DLL模块被全局唯一的32字节的HINSTANCE句柄标识。进程自己还有一个HINSTANCE句柄。所有这些模块句柄都只有在特定的进程内部有效,它们代表了DLL或EXE模块在进程虚拟空间中的起始地址。在Win32中,HINSTANCE和HMODULE的值是相同的,这个两种类型可以替换使用。进程模块句柄几乎总是等于0x400000,而DLL模块的加载地址的缺省句柄是0x10000000。如果程序同时使用了几个DLL模块,每一个都会有不同的HINSTANCE值。这是因为在创建DLL文件时指定了不同的基地址,或者是因为加载程序对DLL代码进行了重定位。
模块句柄对于加载资源特别重要。Win32 的FindResource函数中带有一个HINSTANCE参数。EXE和DLL都有其自己的资源。如果应用程序需要来自于DLL的资源,就将此参数指定为DLL的模块句柄。如果需要EXE文件中包含的资源,就指定EXE的模块句柄。
但是在使用这些句柄之前存在一个问题,你怎样得到它们呢?如果需要得到EXE模块句柄,调用带有Null参数的Win32函数GetModuleHandle;如果需要DLL模块句柄,就调用以DLL文件名为参数的Win32函数GetModuleHandle。

应用程序怎样找到DLL文件

如果应用程序使用LoadLibrary显式链接,那么在这个函数的参数中可以指定DLL文件的完整路径。如果不指定路径,或是进行隐式链接,Windows将遵循下面的搜索顺序来定位DLL:
1. 包含EXE文件的目录,
2. 进程的当前工作目录,
3. Windows系统目录,
4. Windows目录,
5. 列在Path环境变量中的一系列目录。
这里有一个很容易发生错误的陷阱。如果你使用VC++进行项目开发,并且为DLL模块专门创建了一个项目,然后将生成的DLL文件拷贝到系统目录下,从应用程序中调用DLL模块。到目前为止,一切正常。接下来对DLL模块做了一些修改后重新生成了新的DLL文件,但你忘记将新的DLL文件拷贝到系统目录下。下一次当你运行应用程序时,它仍加载了老版本的DLL文件,这可要当心!

调试DLL程序

Microsoft 的VC++是开发和测试DLL的有效工具,只需从DLL项目中运行调试程序即可。当你第一次这样操作时,调试程序会向你询问EXE文件的路径。此后每次在调试程序中运行DLL时,调试程序会自动加载该EXE文件。然后该EXE文件用上面的搜索序列发现DLL文件,这意味着你必须设置Path环境变量让其包含DLL文件的磁盘路径,或者也可以将DLL文件拷贝到搜索序列中的目录路径下。
或者当你调试EXE程序时,在Project Setting中,将Debug选项卡中的Category设置为Additional DLLs。就可以同时调试EXE和它调用的DLL(当然,你需要有DLL的源代码)了。

程序运行:

完成

DLL 导出函数的更多相关文章

  1. DLL导出函数和类的定义区别 __declspec(dllexport)

    DLL导出函数和类的定义区别 __declspec(dllexport) 是有区别的, 请看 : //定义头文件的使用方,是导出还是导入 #if defined(_DLL_API) #ifndef D ...

  2. AFX_MANAGE_STATE(AfxGetStaticModuleState())DLL导出函数包含MFC资源

    AFX_MANAGE_STATE(AfxGetStaticModuleState()) 先看一个例子: .创建一个动态链接到MFC DLL的规则DLL,其内部包含一个对话框资源.指定该对话框ID如下: ...

  3. dll 导出函数名的那些事

    dll 导出函数名的那些事 关键字: VC++  DLL  导出函数 经常使用VC6的Dependency或者是Depends工具查看DLL导出函数的名字,会发现有DLL导出函数的名字有时大不相同,导 ...

  4. C# 遍历DLL导出函数

    C#如何去遍历一个由C++或E语言编写的本地DLL导出函数呢 不过在这里我建议对PE一无所知的人 你或许应先补补这方面的知识,我不知道为什么PE方面的 应用在C#中怎么这么少,我查阅过相关 C#的知识 ...

  5. dll导出函数的两种方式的比较

    最初的网页链接已经挂了, 在此贴一个中间的转载链接 https://blog.csdn.net/zhazhiqiang/article/details/51577523 一 概要 vs中导出 dll的 ...

  6. 动态链接库DLL导出函数并导入使用

    动态链接库DLL导出函数并导入使用 本文完全参考自<vs2008制作dll笔记,回带值样例>. 首先制作DLL文件,在vs2010中新建Win32控制台项目,选择DLL选项,简历头文件,源 ...

  7. Dll 导出函数那些破事

    经常使用VC6的Dependency查看DLL导出函数的名字,会发现有DLL导出函数的名字有时大不相同,导致不同的原因大多是和编译DLL时候指定DLL导出函数的界定符有关系. VC++支持两种语言:即 ...

  8. 使用dumpbin命令查看dll导出函数及重定向输出到文件【轉】

    查看dll导出函数,一般使用Viewdll等第三方工具. VS开发环境中,可以查看32位和64位的dll.具体使用方法如下: 1. 进入VS开发环境,然后Tools -> Visual stud ...

  9. 使用dumpbin命令查看dll导出函数及重定向输出到文件(VS自带)

    以前查看dll导出函数,一般使用Viewdll等第三方工具.但由于Viewdll采用dephi编写,因此仅能查看32位的dll.其实微软已经帮我们提供一个查看dll导出函数的命令,嵌在VS开发环境中, ...

  10. DLL导出函数

    使用DEF文件从DLL导出 模块定义(.def)文件时包含一个或多个描述DLL各种属性的Module语句的文本文件.如果不使用_declspec(dllexport)关键字导出DLL的函数,则DLL需 ...

随机推荐

  1. js div截取字符串的长度

    <div style="width:100%;" id="changdu">这个是字符串的长度</div> $("#chang ...

  2. Elasticsearch的使用场景深入详解

    了解了ES的使用场景,ES的研究.使用.推广才更有价值和意义. 1.场景-:使用Elasticsearch作为主要的后端 传统项目中,搜索引擎是部署在成熟的数据存储的顶部,以提供快速且相关的搜索能力. ...

  3. input 框上传多个文件

    在input标签中加入 multiple 属性,可以在一个输入框中选择多个文件进行上传 <input type="file" name="img" mul ...

  4. BUG--tomcat更改目录失败

    1.问题描述 按照通用的做法,tomcat可以配置运行的网站目录.但是配置后不能正确运行. 配置过程如:http://www.cnblogs.com/SimonGao/p/4905887.html 2 ...

  5. 第十八篇、OC_使用OAStackView FDStackView (第三方框架)可以使用在ios 7及以上的版本

    UILabel *view1 = [[UILabel alloc]init]; view1.text = @"Label1"; view1.backgroundColor = [U ...

  6. A窗口消失B窗口弹出

    一.设计窗口 1) file---new--Application,新建一个窗体,设置该窗体的属性:Caption==登录窗口 2) procedure TForm1.btn1Click(Sender ...

  7. thinkphp 3.2 模型的使用示例

    原来以为thinkPHP的 model 就和PHPCMS一样  就起到一个连接数据库的作用,今天看了视频,才发现这个也是 mvc中的m 使用方法可以使用 D() 方法 下面是 UserControll ...

  8. MFC中在基于对话框的窗体中使用CFileDialog导致菜单栏变灰的解决方案

    CSDN的博客编辑器实在是难用……转战博客园 直接把CSDN发的搬过来了 ————————————————————————————我是分割线———————————————————————————— 第 ...

  9. swift 导航的使用

    导航还是有必要来搞一下的!!!!! 这只是一些基本的导航的使用.....感兴趣的猿可以自己去 废话不多   源码奉上   ⬇️ 首先  delegate里面 在 func application(ap ...

  10. netcat工具的使用

    用途:网络管理工具. 可以读,写TCP或UDP 网络连接.简写为:nc 常见参数: -h  帮助信息 -l 坚挺模式 -n 指定IP地址 -p 指定端口号 -v 详细输出 1 客户端:很容易建立一个客 ...