程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> vc教程 >> VC++動態鏈接庫(DLL)編程深入淺出(二)

VC++動態鏈接庫(DLL)編程深入淺出(二)

編輯:vc教程
   上節給大家介紹了靜態鏈接庫與庫的調試與查看(動態鏈接庫(DLL)編程深入淺出(一)),本節主要介紹非MFC DLL。

4.非MFC DLL

4.1一個簡單的DLL

  第2節給出了以靜態鏈接庫方式提供add函數接口的方法,接下來我們來看看怎樣用動態鏈接庫實現一個同樣功能的add函數。

  如圖6,在VC++中new一個Win32 Dynamic-Link Library工程dllTest(單擊此處下載本工程附件)。注意不要選擇MFC AppWizard(dll),因為用MFC AppWizard(dll)建立的將是第5、6節要講述的MFC 動態鏈接庫。


圖6 建立一個非MFC DLL

  在建立的工程中添加lib.h及lib.cpp文件,源代碼如下:


/* 文件名:lib.h */

#ifndef LIB_H

#define LIB_H

extern "C" int __declspec(dllexport)add(int x, int y);

#endif


/* 文件名:lib.cpp */

#include "lib.h"

int add(int x, int y)

{

return x + y;

}

  與第2節對靜態鏈接庫的調用相似,我們也建立一個與DLL工程處於同一工作區的應用工程dllCall,它調用DLL中的函數add,其源代碼如下:

#include <stdio.h>

#include <Windows.h>

typedef int(*lpAddFun)(int, int); //宏定義函數指針類型

int main(int argc, char *argv[])

{

HINSTANCE hDll; //DLL句柄

lpAddFun addFun; //函數指針

hDll = LoadLibrary("..DebugdllTest.dll");

if (hDll != NULL)

{

addFun = (lpAddFun)GetProcAddress(hDll, "add");

if (addFun != NULL)

{

int result = addFun(2, 3);

printf("%d", result);

}

FreeLibrary(hDll);

}

return 0;

}

  分析上述代碼,dllTest工程中的lib.cpp文件與第2節靜態鏈接庫版本完全相同,不同在於lib.h對函數add的聲明前面添加了__declspec(dllexport)語句。這個語句的含義是聲明函數add為DLL的導出函數。DLL內的函數分為兩種:

  (1)DLL導出函數,可供應用程序調用;

  (2) DLL內部函數,只能在DLL程序使用,應用程序無法調用它們。

  而應用程序對本DLL的調用和對第2節靜態鏈接庫的調用卻有較大差異,下面我們來逐一分析。

  首先,語句typedef int ( * lpAddFun)(int,int)定義了一個與add函數接受參數類型和返回值均相同的函數指針類型。隨後,在main函數中定義了lpAddFun的實例addFun;

  其次,在函數main中定義了一個DLL HINSTANCE句柄實例hDll,通過Win32 Api函數LoadLibrary動態加載了DLL模塊並將DLL模塊句柄賦給了hDll;

  再次,在函數main中通過Win32 Api函數GetProcAddress得到了所加載DLL模塊中函數add的地址並賦給了addFun。經由函數指針addFun進行了對DLL中add函數的調用;

  最後,應用工程使用完DLL後,在函數main中通過Win32 Api函數FreeLibrary釋放了已經加載的DLL模塊。

  通過這個簡單的例子,我們獲知DLL定義和調用的一般概念:

  (1)DLL中需以某種特定的方式聲明導出函數(或變量、類);

  (2)應用工程需以某種特定的方式調用DLL的導出函數(或變量、類)。

  下面我們來對“特定的方式進行”闡述。

4.2 聲明導出函數

  DLL中導出函數的聲明有兩種方式:一種為4.1節例子中給出的在函數聲明中加上__declspec(dllexport),這裡不再舉例說明;另外一種方式是采用模塊定義(.def) 文件聲明,.def文件為鏈接器提供了有關被鏈接程序的導出、屬性及其他方面的信息。

  下面的代碼演示了怎樣同.def文件將函數add聲明為DLL導出函數(需在dllTest工程中添加lib.def文件):

; lib.def : 導出DLL函數

LIBRARY dllTest

EXPORTS

add @ 1

.def文件的規則為:

  (1)LIBRARY語句說明.def文件相應的DLL;

  (2)EXPORTS語句後列出要導出函數的名稱。可以在.def文件中的導出函數名後加@n,表示要導出函數的序號為n(在進行函數調用時,這個序號將發揮其作用);

  (3).def 文件中的注釋由每個注釋行開始處的分號 (;) 指定,且注釋不能與語句共享一行。

  由此可以看出,例子中lib.def文件的含義為生成名為“dllTest”的動態鏈接庫,導出其中的add函數,並指定add函數的序號為1。

4.3 DLL的調用方式

  在4.1節的例子中我們看到了由“LoadLibrary-GetProcAddress-FreeLibrary”系統Api提供的三位一體“

[1] [2] [3] [4] [5] [6] 下一頁

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved