用C語(yǔ)言寫(xiě)動(dòng)態(tài)鏈接庫(kù)_第1頁(yè)
用C語(yǔ)言寫(xiě)動(dòng)態(tài)鏈接庫(kù)_第2頁(yè)
用C語(yǔ)言寫(xiě)動(dòng)態(tài)鏈接庫(kù)_第3頁(yè)
用C語(yǔ)言寫(xiě)動(dòng)態(tài)鏈接庫(kù)_第4頁(yè)
用C語(yǔ)言寫(xiě)動(dòng)態(tài)鏈接庫(kù)_第5頁(yè)
已閱讀5頁(yè),還剩1頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、近來(lái)又有人在群里問(wèn)如何用c語(yǔ)言編制dll文件(動(dòng)態(tài)鏈接庫(kù))。原來(lái)沒(méi)有對(duì)這個(gè)問(wèn)題太在意過(guò),也沒(méi)有嘗試過(guò)任何解決方案,畢竟原來(lái)我是用vb的(現(xiàn)在用.net),做個(gè)dll只不過(guò)是點(diǎn)選一下建立activeX dll工程的圖標(biāo)而已。今天在網(wǎng)上與朋友聊天,看了他指給我的幾個(gè)幾個(gè)文件,用MingW將C程序編譯成dll文件的例子,我恍然大悟,原來(lái)講C程序編譯成dll文件只不過(guò)是在要公開(kāi)的接口函數(shù)聲明前面加上幾個(gè)特定的修飾符而已。于是用dev-cpp建了個(gè)dll的默認(rèn)文檔,一切都很明了。(我把源代碼貼在下面)/*dll.h文件*/#ifndef _DLL_H_#define _DL

2、L_H_#if BUILDING_DLL# define DLLIMPORT _declspec (dllexport)#else /* Not BUILDING_DLL */# define DLLIMPORT _declspec (dllimport)#endif /* Not BUILDING_DLL */DLLIMPORT void HelloWorld (void);#endif

3、0;/* _DLL_H_ */*dllmain.c文件*/* Replace "dll.h" with the name of your header */#include "dll.h"#include <windows.h>#include <stdio.h>#include <stdlib.h>DLLIMPORT void HelloWorld&

4、#160;()    MessageBox (0, "Hello World from DLL!n", "Hi", MB_ICONINFORMATION);BOOL APIENTRY DllMain (HINSTANCE hInst     /* Library instance handle. */ ,&#

5、160;                      DWORD reason        /* Reason this function is being called. */ ,  &#

6、160;                    LPVOID reserved     /* Not used. */ )    switch (reason)       

7、60;  case DLL_PROCESS_ATTACH:        break;      case DLL_PROCESS_DETACH:        break;      case DLL_THREAD_ATTACH:   &

8、#160;    break;      case DLL_THREAD_DETACH:        break;        /* Returns TRUE on success, FALSE on failure */  

9、  return TRUE;關(guān)于以上代碼的幾點(diǎn)解釋?zhuān)阂?、_declspec (dllexport):這是關(guān)鍵,它標(biāo)志著這個(gè)這個(gè)函數(shù)將成為對(duì)外的接口。(以下是我在網(wǎng)上下載的dllexport、dllimport、_declspec的一些說(shuō)明):使用包含在DLL的函數(shù),必須將其導(dǎo)入。導(dǎo)入操作時(shí)通過(guò)dllimport來(lái)完成的,dllexport和dllimport都是vc(visual C+)和bc(Borland C+)所支持的擴(kuò)展的關(guān)鍵字。但是dllexport和dllimport關(guān)鍵字不能被自身所使用,因此它的前面必須有另一個(gè)擴(kuò)展關(guān)鍵

10、字_declspec。通用格式如下:_declspec(specifier)其中specifier是存儲(chǔ)類(lèi)標(biāo)示符。對(duì)于DLL,specifier將是dllexport和dllimport。而且為了簡(jiǎn)化說(shuō)明導(dǎo)入和導(dǎo)出函數(shù)的語(yǔ)句,用一個(gè)宏名來(lái)代替_declspec.在此程序中,使用的是DllExport。如果用戶(hù)的DLL被編譯成一個(gè)C+程序,而且希望C程序也能使用它,就需要增加“C”的連接說(shuō)明。#define DllExport extern "C"_declspec(dllexport),這樣就避免了標(biāo)準(zhǔn)C+命名損壞。(當(dāng)然,如果讀者正在編譯的是

11、C程序,就不要加入extern “C”,因?yàn)椴恍枰?,而且編譯器也不接受它)。二、BOOL APIENTRY DllMain ()說(shuō)明:(以下是我在網(wǎng)上收集的資料)1、每一個(gè)DLL必須有一個(gè)入口點(diǎn),DllMain是一個(gè)缺省的入口函數(shù)。DllMain負(fù)責(zé)初始化(Initialization)和結(jié)束(Termination)工作,每當(dāng)一個(gè)新的進(jìn)程或者該進(jìn)程的新的線(xiàn)程訪(fǎng)問(wèn)DLL時(shí),或者訪(fǎng)問(wèn)DLL的每一個(gè)進(jìn)程或者線(xiàn)程不再使用DLL或者結(jié)束時(shí),都會(huì)調(diào)用DllMain。但是,使用TerminateProcess或TerminateThread結(jié)束進(jìn)程或者線(xiàn)程,不會(huì)調(diào)

12、用DllMain。DllMain的函數(shù)原型:BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved)switch(ul_reason_for_call) case DLL_PROCESS_ATTACH:.case DLL_THREAD_ATTACH:.case DLL_THREAD_DETACH:.case DLL_PROCESS_DETACH:.return TRUE;參數(shù):hMo

13、udle:是動(dòng)態(tài)庫(kù)被調(diào)用時(shí)所傳遞來(lái)的一個(gè)指向自己的句柄(實(shí)際上,它是指向_DGROUP段的一個(gè)選擇符);ul_reason_for_call:是一個(gè)說(shuō)明動(dòng)態(tài)庫(kù)被調(diào)原因的標(biāo)志。當(dāng)進(jìn)程或線(xiàn)程裝入或卸載動(dòng)態(tài)連接庫(kù)的時(shí)候,操作系統(tǒng)調(diào)用入口函數(shù),并說(shuō)明動(dòng)態(tài)連接庫(kù)被調(diào)用的原因。它所有的可能值為:DLL_PROCESS_ATTACH: 進(jìn)程被調(diào)用;DLL_THREAD_ATTACH: 線(xiàn)程被調(diào)用;DLL_PROCESS_DETACH: 進(jìn)程被停止;DLL_THREAD_DETACH: 線(xiàn)程被停止;lpReserved:是一個(gè)被系統(tǒng)所保留的參數(shù)??吹竭@里,我想大家應(yīng)該會(huì)

14、對(duì)將c程序編譯成dll文件有了個(gè)大體的概念。關(guān)于對(duì)于dll文件的使用,我在里做了以下測(cè)試:首先用 2003新建一個(gè)應(yīng)用程序。然后在工程屬性中引用System.Runtime.InteropServices命名空間。然后在默認(rèn)的窗體文件中添加如下代碼:Public Class Form1    Inherits System.Windows.Forms.Form#Region " Windows 窗體設(shè)計(jì)器生成的代碼 "   &

15、#160;Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load    End Sub    Private Sub Button1_Click(ByVal sender As System.Obje

16、ct, ByVal e As System.EventArgs) Handles Button1.Click        Hello()    End SubEnd ClassModule test    Sub main()        Dim 

17、;frm As New Form1        Application.Run(frm)    End Sub    <DllImport("test.dll", EntryPoint:="HelloWorld", setlasterror:=True)> Public Sub Hello()&

18、#160;   End SubEnd Module然后把上面用devcpp生成的test.dll放入工程bin目錄下,測(cè)試成功。關(guān)于dll文件的一點(diǎn)設(shè)想:關(guān)于多語(yǔ)言創(chuàng)建dll文件和動(dòng)態(tài)使用dll文件,我感覺(jué)應(yīng)該是插件技術(shù)plugin技術(shù)最直接的實(shí)現(xiàn)方式。特別是現(xiàn)在的.net平臺(tái),為動(dòng)態(tài)導(dǎo)入dll文件中的函數(shù)提供了更簡(jiǎn)易的方法。一個(gè)實(shí)現(xiàn)插件的基本思想可以是,在主程序和插件程序內(nèi)做出一個(gè)規(guī)定的通訊方式,比如將一個(gè)可以代表使用插件功能的對(duì)象,由主程序創(chuàng)建對(duì)應(yīng)插件程序的對(duì)象,然后由插件程序傳址調(diào)用,調(diào)用修改后的對(duì)象中保存了插件功能信息(比如插件名稱(chēng)、功

19、能函數(shù)指針等),然后再由主程序進(jìn)行處理。以下是網(wǎng)上摘抄的一點(diǎn)資料:動(dòng)態(tài)鏈接庫(kù)中定義有兩種函數(shù):導(dǎo)出函數(shù)(export function)和內(nèi)部函數(shù)(internal function)。導(dǎo)出函數(shù)可以被其它模塊調(diào)用,內(nèi)部函數(shù)在定義它們的DLL程序內(nèi)部使用。輸出函數(shù)的方法有以下幾種:1、傳統(tǒng)的方法在模塊定義文件的EXPORT部分指定要輸入的函數(shù)或者變量。語(yǔ)法格式如下:entryname=internalname ordinalNONAME DATA PRIVATE其中:entryname是輸出的函數(shù)或者數(shù)據(jù)被引用的名稱(chēng);internalname同e

20、ntryname;ordinal表示在輸出表中的順序號(hào)(index);NONAME僅僅在按順序號(hào)輸出時(shí)被使用(不使用entryname);DATA表示輸出的是數(shù)據(jù)項(xiàng),使用DLL輸出數(shù)據(jù)的程序必須聲明該數(shù)據(jù)項(xiàng)為_(kāi)declspec(dllimport)。上述各項(xiàng)中,只有entryname項(xiàng)是必須的,其他可以省略。對(duì)于“C”函數(shù)來(lái)說(shuō),entryname可以等同于函數(shù)名;但是對(duì)“C+”函數(shù)(成員函數(shù)、非成員函數(shù))來(lái)說(shuō),entryname是修飾名。可以從.map映像文件中得到要輸出函數(shù)的修飾名,或者使用DUMPBIN /SYMBOLS得到,然后把它們寫(xiě)在.def文件的輸出模塊。DUMPBIN是

21、VC提供的一個(gè)工具。如果要輸出一個(gè)“C+”類(lèi),則把要輸出的數(shù)據(jù)和成員的修飾名都寫(xiě)入.def模塊定義文件。2、在命令行輸出對(duì)鏈接程序LINK指定/EXPORT命令行參數(shù),輸出有關(guān)函數(shù)。3、使用MFC提供的修飾符號(hào)_declspec(dllexport)在要輸出的函數(shù)、類(lèi)、數(shù)據(jù)的聲明前加上_declspec(dllexport)的修飾符,表示輸出。_declspec(dllexport)在C調(diào)用約定、C編譯情況下可以去掉輸出函數(shù)名的下劃線(xiàn)前綴。extern "C"使得在C+中使用C編譯方式成為可能。在“C+”下定義“C”函數(shù),需要加extern “C”關(guān)鍵詞

22、。用extern "C"來(lái)指明該函數(shù)使用C編譯方式。輸出的“C”函數(shù)可以從“C”代碼里調(diào)用。例如,在一個(gè)C+文件中,有如下函數(shù):extern "C" void _declspec(dllexport) _cdecl Test(int var);其輸出函數(shù)名為:Test MFC提供了一些宏,就有這樣的作用。AFX_CLASS_IMPORT:_declspec(dllexport)AFX_API_IMPORT:_declspec(dllexport)AFX_DATA_IMPORT:_declspec(dll

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論