c++中.dll與.lib文件的生成與使用的詳解


兩種庫:

•  包含了函數所在的DLL文件和文件中函數位置的信息(入口),代碼由運行時加載在進程空間中的DLL提供,稱為動態鏈接庫dynamic link library。
•  包含函數代碼本身,在編譯時直接將代碼加入程序當中,稱為靜態鏈接庫static link library。
共有兩種鏈接方式:

•  動態鏈接使用動態鏈接庫,允許可執行模塊(.dll文件或.exe文件)僅包含在運行時定位DLL函數的可執行代碼所需的信息。
•  靜態鏈接使用靜態鏈接庫,鏈接器從靜態鏈接庫LIB獲取所有被引用函數,並將庫同代碼一起放到可執行文件中。

兩種文件的區別

使用lib需注意兩個文件:

•.h頭文件,包含lib中說明輸出的類或符號原型或數據結構。應用程序調用lib時,需要將該文件包含入應用程序的源文件中。
•.LIB文件。

使用dll需注意三個文件:

•.h頭文件,包含dll中說明輸出的類或符號原型或數據結構的.h文件。應用程序調用dll時,需要將該文件包含入應用程序的源文件中。
•.LIB文件,是dll在編譯、鏈接成功之后生成的文件,作用是當其他應用程序調用dll時,需要將該文件引入應用程序,否則產生錯誤(如果不想用lib文件或者沒有lib文件,可以用WIN32 API函數LoadLibrary、GetProcAddress裝載)。
•dll文件,真正的可執行文件,開發成功后的應用程序在發布時,只需要有.exe文件和.dll文件,並不需要.lib文件和.h頭文件。

1.生成lib文件

  首先,我們先建立一個控制台工程(新建->工程->控制台程序),添加sub.cpp以及sub.h文件。

//sub.h
#ifndef _SUB_H
#define _SUB_H
void sub(int a,int b);
#endif
//sub.cpp
#include "sub.h"
#include <iostream>
void sub(int a,int b)
{
    std::cout<<(a-b)<<std::endl;
}

由於在工程中,沒有main()函數,所以直接編譯出錯。這時,要右鍵點擊工程,並選擇工程屬性,出現下圖,選擇靜態鏈接庫即可。

這時候再按F7,build solution即可產生lib文件。在Debug中只生成.lib文件。

2.生成dll文件

  生成dll文件的過程與上面的過程是一樣的,只是在選擇Dynamic Library(.dll)即可。在Debug中會生成一個.lib和.dll兩種文件。

3.兩種文件的使用

  在使用時,靜態鏈接庫只要把.h和.lib文件加入到工程文件夾中即可。而動態鏈接庫要把.h、.lib和.dll文件加入到工程中。

#include <iostream>
#include "sub.h"  //鏈接庫的頭文件
using namespaces std;
#pragma comment(lib,"sub.lib") //加入鏈接庫
int main()
{
    sub(5,4);
    return 0;
}

把.h和.lib的文件放在相應的目錄下 ,有時候有錯誤,但是也能運行成功。

感覺靠譜的方法是像一些標准庫的方法,添加包含目錄和庫目錄,添加依賴項。

第一種方法:

把這個庫拷貝到工程目錄下,(最好拷貝到vs編譯器可以找到的目錄下,這個路徑在tools---options---projects and soulutions---show libraray的目錄下,至於這些目錄如何查看,在以前的博客中有相關的文章,這樣可以方便編譯器編譯時候查找到這個庫文件)

之后把庫頭文件拷貝到當前目錄下
在libtest的實現文件中,首先包含這個頭文件,然后使用pragma指令指明鏈接庫chang.lib,然后再工程中使用這個函數中的庫就可以了

第二種方法:

這個庫文件可以在任意路徑下,首先在tools---options---projects and soulutions---show libraray目錄下添加這個庫文件所在的目錄
然后再在工程屬性---configuration properties---Linker---Addtional library directories下添加這個庫文件所在的目錄

在工程屬性---configuration properties---Linker---Input---Addtional dependencies添加要使用的庫的名字,現在這個就是chang.lib
之后把庫文件的頭文件拷貝到libtest工程的源文件文件夾下
最后在源文件中就可以不使用pragma指令了

 

//另注:生成 .lib文件的工程中可以沒有main()函數。

//另注:工程test1之所以生成的是 .lib文件而不是 .dll文件,是因為test1與test2在同一個解決方案中,沒有涉及外部接口。

 實驗表明:lib庫方法二像opencv的配置方式,正確。

注意:這個時候會再解決方案文件夾下的debug或release文件夾下生成test1工程的.lib文件test1.lib,在進行編譯的時候會將這個靜態庫的東西完全鏈接進入exe可執行文件,這樣生成的可執行文件可以拷貝出來到任何其他windows平台的計算機上就可以運行;一個缺點就是如果代碼很大的話,生成的.exe可執行文件會很大,靜態鏈接方式就是會再編譯的時候把所有需要的東西編譯鏈接進可執行程序;

如果使用生成的.dll,這樣生成的exe會相對小一些,但是如果將這個可執行文件拷貝到其他windows平台的計算機上,很可能就會無法運行,就需要把這個生成的dll文件拷貝到運行該程序的計算機上的所需要的制定目錄下才可以(一般就是system32目錄下);缺點就是比較麻煩;

記得以前做過的一次作業就是這樣,寫的一個MFC的應用程序,拷貝到別人電腦上死活跑不住,結果發現默認的編譯方式是動態鏈接編譯方式,之后設置成靜態鏈接進行重編譯,發現生成的可執行文件有了數倍的增長,但是放到別人的windows平台的計算機上就很順利地運行了。

 

參考:

在同一個解決方案下,如何從一個工程中調用另外一個工程的函數

導出C函數的:
LIB的:
vs下制作和使用.lib靜態庫
DLL的:
DLL編寫教程 - MDA之路

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM