应用程序使用DLL可以采用两种方式:

一种是隐式链接,另一种是显式链接。在使用DLL之前首先要知道DLL中函数的结构信息。

Visual C++6.0在VC\bin目录下提供了一个名为Dumpbin.exe的小程序,用它可以查看DLL文件中的函数结构。另外,Windows系统将遵循下面的搜索顺序来定位DLL:

1.包含EXE文件的目录,

2.进程的当前工作目录,

3.Windows系统目录,

4.Windows目录,

5.列在Path环境变量中的一系列目录。

1.隐式链接

  隐式链接就是在程序开始执行时就将DLL文件加载到应用程序当中。实现隐式链接很容易,只要将导入函数关键字_declspec(dllimport)函数名等写到应用程序相应的头文件中就可以了。

隐式链接采用静态加载的方式,比较简单,需要.h、.lib、.dll三件套。新建“控制台应用程序”或“空项目”。配置如下:

项目->属性->配置属性->VC++ 目录-> 在“包含目录”里添加头文件Mydll.h所在的目录 
项目->属性->配置属性->VC++ 目录-> 在“库目录”里添加头文件Mydll.lib所在的目录 
项目->属性->配置属性->链接器->输入-> 在“附加依赖项”里添加“Mydll.lib”(若有多个 lib 则以空格隔开)
下面的例子通过隐式链接调用MyDll.dll库中的Min函数。首先生成一个项目为testDLL,在testDLL.h、testDLL.cpp文件中分别输入如下代码:

//TestDLL.h
#pragma comment(lib,"MyDll.lib")
extern "C"_declspec(dllimport) int Max(int a,int b);
extern "C"_declspec(dllimport) int Min(int a,int b);
//TestDll.cpp
#include
#include"Dlltest.h"
void main()
{
int a;
a=min(,)
printf("比较的结果为%d\n",a);
}

在创建DllTest.exe文件之前,要先将MyDLL.dll和MyDLL.lib拷贝到当前工程可执行文件所在的目录下面(非常重要),也可以拷贝到windows的System目录下。如果DLL使用的是def文件,要删除testDLL.h文件中关键字extern "C"。testDLL.h文件中的关键字Progam commit是要Visual C+的编译器在link时,链接到MyDll.lib文件,当然,开发人员也可以不使用#pragma comment(lib,"MyDLL.lib")语句,而直接在工程的Setting->Link页的Object/Moduls栏填入MyDll.lib既可。

2.显式链接

  显式链接是应用程序在执行过程中随时可以加载DLL文件,也可以随时卸载DLL文件,这是隐式链接所无法作到的,所以显式链接具有更好的灵活性,对于解释性语言更为合适。不过实现显式链接要麻烦一些。在应用程序中用LoadLibrary或MFC提供的AfxLoadLibrary显式的将自己所做的动态链接库调进来,动态链接库的文件名即是上述两个函数的参数,此后再用GetProcAddress()获取想要引入的函数。自此,你就可以象使用如同在应用程序自定义的函数一样来调用此引入函数了。在应用程序退出之前,应该用FreeLibrary或MFC提供的AfxFreeLibrary释放动态链接库。下面是通过显式链接调用DLL中的Max函数的例子。

#include
void main(void)
{
  typedef int(*pMax)(int a,int b);
  typedef int(*pMin)(int a,int b);
  HINSTANCE hDLL;
  PMax Max
  HDLL=LoadLibrary("MyDll.dll");//加载动态链接库MyDll.dll文件;
  Max=(pMax)GetProcAddress(hDLL,"Max");
  A=Max(,);
  Printf("比较的结果为%d\n",a);
  FreeLibrary(hDLL);//卸载MyDll.dll文件;
}

在上例中使用类型定义关键字typedef,定义指向和DLL中相同的函数原型指针,然后通过LoadLibray()将DLL加载到当前的应用程序中并返回当前DLL文件的句柄,然后通过GetProcAddress()函数获取导入到应用程序中的函数指针,函数调用完毕后,使用FreeLibrary()卸载DLL文件。在编译程序之前,首先要将DLL文件拷贝到工程所在的目录或Windows系统目录下。

  使用显式链接应用程序编译时不需要使用相应的Lib文件。另外,使用GetProcAddress()函数时,可以利用MAKEINTRESOURCE()函数直接使用DLL中函数出现的顺序号,如将GetProcAddress(hDLL,"Min")改为GetProcAddress(hDLL, MAKEINTRESOURCE(2))(函数Min()在DLL中的顺序号是2),这样调用DLL中的函数速度很快,但是要记住函数的使用序号,否则会发生错误。

在C++中调用DLL中的函数 (2)的更多相关文章

  1. 在VS2012中采用C++中调用DLL中的函数 (4)

    这两天因为需要用到VS2012来生成一个DLL代码,但是之前并没有用过DLL相关的内容,从昨天开始尝试调试DLL的文件调用,起初笔者在网络上找到了3片采用VSXXX版本进行调试的例子,相关的内容见本人 ...

  2. 在C++中调用DLL中的函数 (3)

    1.dll的优点 代码复用是提高软件开发效率的重要途径.一般而言,只要某部分代码具有通用性,就可将它构造成相对独立的功能模块并在之后的项目中重复使用.比较常见的例子是各种应用程序框架,ATL.MFC等 ...

  3. 在C++中调用DLL中的函数

    如何在C++中调用DLL中的函数 应用程序使用DLL可以采用两种方式:一种是隐式链接,另一种是显式链接.在使用DLL之前首先要知道DLL中函数的结构信息.Visual C++6.0在VC\bin目录下 ...

  4. 【原创】在VS2012中采用C++中调用DLL中的函数(4)

    这两天因为需要用到VS2012来生成一个DLL代码,但是之前并没有用过DLL相关的内容,从昨天开始尝试调试DLL的文件调用,起初笔者在网络上找到了3片采用VSXXX版本进行调试的例子,相关的内容见本人 ...

  5. 在C++中调用DLL中的函数(3)

    1.dll的优点 代码复用是提高软件开发效率的重要途径.一般而言,只要某部分代码具有通用性,就可将它构造成相对独立的功能模块并在之后的项目中重复使用.比较常见的例子是各种应用程序框架,ATL.MFC等 ...

  6. 在VS2012中采用C++中调用DLL中的函数(4)

    转自:http://www.cnblogs.com/woshitianma/p/3683495.html 这两天因为需要用到VS2012来生成一个DLL代码,但是之前并没有用过DLL相关的内容,从昨天 ...

  7. 在C++中调用DLL中的函数(2)

    本文转自:http://blog.sina.com.cn/s/blog_53004b4901009h3b.html 应用程序使用DLL可以采用两种方式: 一种是隐式链接,另一种是显式链接.在使用DLL ...

  8. Qt调用dll中的功能函数

    声明: 事先我已经自己动手写了一个简单的dll文件(myDLL.dll),C版接口的.并且用我前两篇有关DLL文章里面的方法,从dll中导出了导入库(.lib)文件,dll中有两个函数,原型如下:   ...

  9. Unity C# 调用 C++ DLL 并在 DLL 中调用 C# 的回调函数

    Unity C# 调用 C++ DLL 并在 DLL 中调用 C# 的回调函数~~~    呵呵... 看着有点晕.. 再解释一下就是 在Unity中 使用 C# 调用 C++ 写的 DLL, 但是在 ...

随机推荐

  1. (C/C++) Interview in English - Threading

    Q. What's the process and threads and what's the difference between them? A.  A process is an execut ...

  2. eclipse 每次切换工作空间都要重新配置

    首先,导出T1中的配置打开T1,选择file --> Export --> 在弹出框中选择General 下的preference --> next --> 在export p ...

  3. mysql事件

    文章参考自http://blog.163.com/duanpeng3@126/blog/static/8854373520105182123112/在使用这个功能之前必须确保event_schedul ...

  4. HDU 3001 Traveling(状压DP)

    题目大意:10个点的TSP问题,但是要求每个点最多走两边,不是只可以走一次,所以要用三进制的状态压缩解决这个问题.可以预处理每个状态的第k位是什么. 原代码链接:http://blog.csdn.ne ...

  5. U8Bom查询

    select temp.*,Inventory.cInvCode,Inventory.cInvName,Inventory.cInvStd from ( select b.InvCode as 'PI ...

  6. 使用Async和Await进行异步编程(C#版 适用于VS2015) z

    你可以使用异步编程来避免你的应用程序的性能瓶颈并且加强总体的响应.然而,用传统的技术来写异步应用是复杂的,同时编写,调试和维护都很困难. VS2012介绍了简单的方法,那就是异步编程,它在.Net F ...

  7. c#内置颜色大全

  8. 89、Android EditText 悬浮停靠

    package com.willen.topFloatDemo; import android.content.Context; import android.os.Handler; import a ...

  9. C++学习13 类class和结构体struct的区别

    C++保留了C语言的 struct,并且加以扩充.在C语言中,struct 只能包含数据成员,不能包含成员函数.而在C++中,struct 类似于 class,既可以包含数据成员,又可以包含成员函数. ...

  10. Redis链接上不的问题

    问题描述: 同样配置的redis及系统环境,在两台服务器(A.B两台服务)上部署,但是其中一台(A),运行一段时间,就链接不上了,从开始运行redis到redis链接不上,这个时间间隔,不一定有时候是 ...