Windows动态链接库DLL的使用

windows程序设计使用动态链接库可以有效的分隔大型项目的模块,DLL里面主要提供函数的调用接口(函数名)供其他的外部引用程序调用,调用者在完全不知道动态链接库中的实现方式的情况下,仍然能根据其提供的函数名,函数类型, 和函数的参数实现调用。windows程序中创建DLL时可以选择Win32 Dynamic-Link Library和MFC AppWizard[dll]两者类型的DLL两者的区别如下:

a、Non-MFC DLL:指的是不用MFC的类库结构,直接用C语言写的DLL,其输出的函数一般用的是标准C接口,并能被非MFC或MFC编写的应用程序所调用。

b、Regular DLL:和下述的Extension Dlls一样,是用MFC类库编写的。明显的特点是在源文件里有一个继承CWinApp的类。其又可细分成静态连接到MFC和动态连接到MFC上的。


c、Extension DLL:用来实现从MFC所继承下来的类的重新利用,也就是说,用这种类型的动态连接库,可以用来输出一个从MFC所继承下来的类。它输出的函数仅可以被使用MFC且动态链接到MFC的应用程序使用。可以从MFC继承你所想要的、更适于你自己用的类,并把它提供给你的应用程序。你也可随意的给你的应用程序提供MFC或MFC继承类的对象指针。Extension DLL使用MFC的动态连接版本所创建的,并且它只被用MFC类库所编写的应用程序所调用。

 

对于Win32 Dynamic-Link Library创建的DLL使用过程如下:

1. 创建基于Win32 Dynamic-Link Library 的一个工程

2. 分别创建.cpp和.h文件,.h文件中定义导出函数,也就是供其他程序调用的函数, .cpp实现.h中定义的导出函数

例如:

在.h 文件中定义两个导出函数MaxYueShu, MinBeiShu

#ifndef ADDDLL_H
#define ADDDLL_H
extern "C" int _declspec(dllexport)MaxYueShu(int num1, int num2);//定义导出函数
extern "C" int _declspec(dllexport)MinBeiShu(int num1, int num2);
#endif

在.cpp文件中实现导出函数,这里为求两个数的最大公约数和最下公倍数

#include "addDLL.h"
int MaxYueShu(int num1, int num2)
{
 int temp;
 while (num1 % num2)
 {
  temp = num2;
  num2 = num1 % num2;
  num1 = temp;
 }
 return num2;
}
int MinBeiShu(int num1, int num2)
{
 int temp;
 if(num1 < num2)
 {
  temp = num1;
  num1 = num2;
  num2 = temp;
 }
 for(int i = 1; i <= num2; i++)
 {
  if(!((num1 * i) % num2))
  {
   return num1 * i;
  }
 }
}

然后编译连接就可以在Debug目录下生成相应的dll文件,这样就完成了一个dll文件的创建,接下来是引用它,重新创建一个工程,将上述生成的dll文件复制到该工程的Debug目录下,然后在需要引用的地方添加代码

 typedef int(*lpAddFun)(int, int);//声明函数指针
 HINSTANCE hDll;//定义接收dll文件的句柄
 lpAddFun addFun;
 hDll = LoadLibrary("..\\Debug\\AddDLL2.dll");//载入DLL
 if(hDll != NULL)
 {
  addFun = (lpAddFun)GetProcAddress(hDll, "MinBeiShu");//获取DLL中MinBeiShu函数的地址
  if(addFun != NULL)
  {
   int result = addFun(2, 3); //调用函数
   CString str;
   str.Format("%d", result);
   m_Result.SetWindowText(str);
  }
  FreeLibrary(hDll);//释放DLL
 }

 

这样就完成了一个Win32 Dynamic-Link Library的DLL使用。

 

接下来介绍MFC AppWizard[dll](常规dll)的使用方法,常规DLL又分为静态连接,动态连接,和扩展DLL,因为动态连接到MFC的常规DLL 比较小,所以介绍动态连接到MFC的常规DLL的使用方法;

1. 创建MFC AppWizard[dll工程的DLL

2. 在.def文件中添加导出函数,下列声明了两个导出函数同上,

例如:

; maxYueshuAndMinBeishu.def : Declares the module parameters for the DLL.

LIBRARY      "maxYueshuAndMinBeishu"//DLL的标识符(名字)
DESCRIPTION  'maxYueshuAndMinBeishu Windows Dynamic Link Library'//DLL的描述

EXPORTS
    ; Explicit exports can go here
 MaxYueShu;//导出函数
 MinBeiShu;

3. 在.h文件中声明导出函数

// maxYueshuAndMinBeishu.h : main header file for the MAXYUESHUANDMINBEISHU DLL
//

#if !defined(AFX_MAXYUESHUANDMINBEISHU_H__4FCC0A2B_E9E9_4E33_964E_B4627D2195C6__INCLUDED_)
#define AFX_MAXYUESHUANDMINBEISHU_H__4FCC0A2B_E9E9_4E33_964E_B4627D2195C6__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#ifndef __AFXWIN_H__
 #error include 'stdafx.h' before including this file for PCH
#endif

#include "resource.h"  // main symbols

/
// CMaxYueshuAndMinBeishuApp
// See maxYueshuAndMinBeishu.cpp for the implementation of this class
//

class CMaxYueshuAndMinBeishuApp : public CWinApp
{
public:
 CMaxYueshuAndMinBeishuApp();

// Overrides
 // ClassWizard generated virtual function overrides
 //{{AFX_VIRTUAL(CMaxYueshuAndMinBeishuApp)
 //}}AFX_VIRTUAL

 //{{AFX_MSG(CMaxYueshuAndMinBeishuApp)
  // NOTE - the ClassWizard will add and remove member functions here.
  //    DO NOT EDIT what you see in these blocks of generated code !
 //}}AFX_MSG
 DECLARE_MESSAGE_MAP()
};

extern "C" int PASCAL MaxYueShu(int num1, int num2);
extern "C" int PASCAL MinBeiShu(int num1, int num2);
/

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_MAXYUESHUANDMINBEISHU_H__4FCC0A2B_E9E9_4E33_964E_B4627D2195C6__INCLUDED_)

 

4. 然后在.cpp文件中实现

// maxYueshuAndMinBeishu.cpp : Defines the initialization routines for the DLL.
//

#include "stdafx.h"
#include "maxYueshuAndMinBeishu.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

//
// Note!
//
//  If this DLL is dynamically linked against the MFC
//  DLLs, any functions exported from this DLL which
//  call into MFC must have the AFX_MANAGE_STATE macro
//  added at the very beginning of the function.
//
//  For example:
//
//  extern "C" BOOL PASCAL EXPORT ExportedFunction()
//  {
//   AFX_MANAGE_STATE(AfxGetStaticModuleState());
//   // normal function body here
//  }
//
//  It is very important that this macro appear in each
//  function, prior to any calls into MFC.  This means that
//  it must appear as the first statement within the
//  function, even before any object variable declarations
//  as their constructors may generate calls into the MFC
//  DLL.
//
//  Please see MFC Technical Notes 33 and 58 for additional
//  details.
//

/
// CMaxYueshuAndMinBeishuApp

BEGIN_MESSAGE_MAP(CMaxYueshuAndMinBeishuApp, CWinApp)
 //{{AFX_MSG_MAP(CMaxYueshuAndMinBeishuApp)
  // NOTE - the ClassWizard will add and remove mapping macros here.
  //    DO NOT EDIT what you see in these blocks of generated code!
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CMaxYueshuAndMinBeishuApp construction

CMaxYueshuAndMinBeishuApp::CMaxYueshuAndMinBeishuApp()
{
 // TODO: add construction code here,
 // Place all significant initialization in InitInstance
}

/
// The one and only CMaxYueshuAndMinBeishuApp object

CMaxYueshuAndMinBeishuApp theApp;

//实现导出函数
extern "C" int PASCAL MaxYueShu(int num1, int num2)
{
 AFX_MANAGE_STATE(AfxGetStaticModuleState());
 
 int temp;
 while (num1 % num2)
 {
  temp = num2;
  num2 = num1 % num2;
  num1 = temp;
 }
 return num2;
}

extern "C"  int PASCAL MinBeiShu(int num1, int num2)
{
 AFX_MANAGE_STATE(AfxGetStaticModuleState());
 int temp;
 if(num1 < num2)
 {
  temp = num1;
  num1 = num2;
  num2 = temp;
 }
 for(int i = 1; i <= num2; i++)
 {
  if(!((num1 * i) % num2))
  {
   return num1 * i;
  }
 }
}

 

5. 编译,连接,同样会在Debug目录下生成了相应的dll文件,然后就可以供其他的程序调用

新建一个MFC工程,调用代码如下:

 UpdateData(true);
 int (__stdcall * lpfn)(int, int);//声明函数指针
 HINSTANCE hinst;//声明DLL句柄
 hinst = LoadLibrary("maxYueshuAndMinBeishu.dll");//载入DLL
 if(hinst == NULL)
 {
  AfxMessageBox("载入DLL失败!");
  return;
 }
 (FARPROC & )lpfn = GetProcAddress(hinst, "MaxYueShu");//获取MaxYueShu函数地址,GetProcAddress函数返回的是一个FARPROC
 if(lpfn == NULL)
 {
  AfxMessageBox("读取函数地址失败!");
  return;
 }
 int result = lpfn(m_Num1, m_Num2);
 CString str;
 str.Format("%d", result);
 m_Result.SetWindowText(str);
 FreeLibrary(hinst);

这样就完成了一次调用。

 

 

    

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值