C++ C# dll基本操作

.dll 動態鏈接庫,在程序運行時鏈接(run-time linked),爲PE(portable executable)格式。像exe、dll、fon、mod、drv、ocx等等都是動態鏈接庫。

.lib 靜態鏈接庫,在編譯時與程序鏈接(link-time linked),會嵌入到程序中,在應用時需要在源代碼中引用lib對應的頭文件.h,這些頭文件告訴編譯器.lib中有什麼。

一般在生成.dll時會伴生一個.lib,這個.lib被編譯到程序文件中,在程序運行時告訴操作系統將要加載的.dll,其中還包含有文件名,順序表。
dll的創建主要有兩種方法:一是使用_declspec(dlexport)創建dll,二是用模塊定義(.def)問價創建dll。

VC IDE爲了實現程序調試,會生成.PDB(程序數據庫),裏面包含有原文件調用的文件信息和行信息,這樣就可以逐行調試了。


怎麼用

必須注意,如果程序想要訪問某個dll中的函數,那麼這個函數必須是已經被到處的函數,這可以用Dumpbin.exe的小程序來查看DLL文件中的函數結構。
1.隱式的加載時鏈接
這個需要伴生的LIB文件,運行時,系統會尋這個DLL,尋找路徑順序如下:

  • 可執行文件所在的目錄。
  • 當前程序的工程目錄。
  • 系統目錄(GetSysemDirectory列表內容函數可以得到)
  • windows目錄。
  • 列在PATH環境變量中的所有目錄。

    那麼LIB文件怎麼加載呢?
    1.直接加入到工程文件列表中,在VC中打開Fileview一頁,選中工程名,單擊鼠標右鍵,然後選中“Add Files to Project ”菜單,然後選擇LIB文件。
    2.打開工程Projectseting菜單,選中Link,然後再Object/library modules 下的文本框中輸入DLL的LIB文件。
    3.通過代碼,加入預編譯指令#pragma comment(lib,”*.lib”),這種方法優點是可以利用條件預編譯指令鏈接不同版本的LIB文件,如Debug方式產生的Debug版本(如Waxd.lib),或者Release版本(如Waxr.lib)。

//Dlltest.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(8,10)
printf("比較的結果爲%d\n",a);
}

加載後還需要把對應的頭文件包含進來,頭文件有定義函數的原型。

2.顯示的運行時鏈接
隱式鏈接需要頭文件和LIB文件,有點多,如果只提供DLL文件就只能用顯式鏈接,調用API函數來對DLL文件進行加載與卸載。

  • 使用Windows API函數Load Library或者MFC提供的AfxLoadLibrary將DLL模塊映像到進程的內存空間,對DLL模塊進行動態加載。
  • 使用GetProcAddress函數得到要調用DLL中的函數的指針。
  • 不用DLL時,用Free Library函數或者AfxFreeLibrary函數從進程的地址空間顯式卸載DLL。
  • 使用顯式鏈接應用程序編譯時不需要使用相應的Lib文件。另外,使用GetProcAddress()函數時,可以利用MAKEINTRESOURCE()函數直接使用DLL中函數出現的順序號,如將GetProcAddress(hDLL,”Min”)改爲GetProcAddress(hDLL, MAKEINTRESOURCE(2))(函數Min()在DLL中的順序號是2),這樣調用DLL中的函數速度很快,但是要記住函數的使用序號,否則會發生錯誤。

    那麼DLL怎麼調用呢:
    (一).靜態調用其步驟如下:
    1.把你的youApp.DLL拷到你目標工程(需調用youApp.DLL的工程)的Debug目錄下;
    2.把你的youApp.lib拷到你目標工程(需調用youApp.DLL的工程)目錄下;
    3.把你的youApp.h(包含輸出函數的定義)拷到你目標工程(需調用youApp.DLL的工程)目錄下;
    4.打開你的目標工程選中工程,選擇Visual C++的Project主菜單的Settings菜單;
    5.執行第4步後,VC將會彈出一個對話框,在對話框的多頁顯示控件中選擇Link頁。然後在Object/library modules輸入框中輸入:youApp.lib
    6.選擇你的目標工程Head Files加入:youApp.h文件;
    7.最後在你目標工程(*.cpp,需要調用DLL中的函數)中包含你的:#include “youApp.h”
    注:youApp是你DLL的工程名。

(二).動態調用其程序如下:
動態調用時只需做靜態調用步驟1.

{
     HINSTANCE hDllInst = LoadLibrary("youApp.DLL");
     if(hDllInst)
     {         typedef DWORD (WINAPI*MYFUNC)(DWORD,DWORD);
        MYFUNCyouFuntionNameAlias=NULL;
       // youFuntionNameAlias 函數別名
       youFuntionNameAlias= (MYFUNC)GetProcAddress(hDllInst,"youFuntionName");
      // youFuntionName 在DLL中聲明的函數名
       if(youFuntionNameAlias)
      {
            youFuntionNameAlias(param1,param2);
        }
        FreeLibrary(hDllInst);
  }
}

顯式(靜態)調用:
LIB + DLL + .H,注意.H中dllexport改爲dllimport
隱式(動態)調用:
DLL + 函數原型聲明,先LoadLibrary,再GetProcAddress(即找到DLL中函數的地址),不用後FreeLibrary



__declspec(dllexport) 聲明一個導入函數,從本DLL文件導出去,給別人用。一般在DEF文件中定義導出哪些函數的方法,但是如果DLL裏面全部是C++的類的話,就無法從DEF裏指定導出的函數,只能用這個函數。

__declspec(dllimport) 聲明一個導出函數,給我自己用,從別的DLL導入進來的。

dll的生成與使用:轉載鏈接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章