Windows動態連結程式庫DLL的使用

來源:互聯網
上載者:User

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);

這樣就完成了一次調用。

 

 

    

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.