1. 程式人生 > >為何Windows下的動態庫總伴隨一個靜態庫?

為何Windows下的動態庫總伴隨一個靜態庫?

今天同學來問了一個問題:Visual Studio中生成的動態庫總是伴隨著一個靜態庫檔案,我把這兩個檔案同樣進行重新命名之後還能不能使用?

我對VS下的動態庫的生成並不是很熟悉,表示無法回答這個問題。但這個問題本身卻也讓我產生了疑問:動態庫真的需要總是伴隨著一個靜態庫?根據我在Linux下的經驗,這兩種形式的程式碼庫是沒有什麼依賴關係的。 那在Windows下到底是怎麼回事?帶著這些疑問,我去搜索了一下。下面將得到的結論和一些相關知識進行總結。

靜態連結庫(.lib檔案)其實是程式碼的簡單集合,在Linux下副檔名為.a,表示archive(歸檔)之意。它只是將編譯後的目的碼(.o檔案)進行簡單的歸檔,沒什麼特殊之處。我曾試過將Windows下的foo.lib檔案直接命名為foo.a,直接在Linux下使用 (當然,前提是他們含有的目的碼必須一樣,即編譯時目標平臺是一致的)。這些庫在連結時被連結進可執行檔案,如同.o檔案被連結一樣。靜態庫的作用無非是將多個.o整合為一個,便於管理和分享而已。

動態連結庫(.dll檔案)則相對複雜一些。動態庫中的程式碼是在執行時根據需要載入的。由於這裡面的程式碼在載入進記憶體後可以被多個程式共享,因此又稱為共享庫,在Linux下的副檔名為.so,表示shared objects(共享的目的碼)之意。

Windows下用VS建立DLL專案生成.dll檔案時,一般會伴隨生成一個.lib檔案;使用這個.dll檔案時,需要將伴隨的.lib加進連結選項。事實上,這裡的.lib檔案中只包含簡單的匯出定義,實際的程式碼還是在.dll檔案中。這裡的.lib檔案並非是上面提到的 靜態庫,而是動態連結庫的匯入庫(Import Libary)。雖然共用副檔名,但它們的內容是完全不一樣的。匯入庫只在連結的時候需要,程式執行的時候只需要.dll檔案即可。此外,DLL專案中必須至少匯出一個函式、變數或者類才會有.lib生成, 沒有匯出的話就不生成.lib檔案。由於一般情況下DLL專案都是為了匯出符號給別的專案用,所以才給人一種動態庫總伴隨著一個“靜態庫”檔案的假象。

回到同學的問題。伴隨的那個.lib檔案裡有相應的.dll檔案的名字和一個指明.dll檔案中函式入口的順序表。如果把.dll檔案的名稱改了,.lib檔案中相應的名字還是原來的檔名,應該就會找不到相應的.dll檔案了。 但其實.dll檔案在沒有.lib檔案的情況下也是可以使用的:通過WIN32 API函式LoadLibrary、GetProcAddress等函式來呼叫.dll中的函式即可。但這樣比起有.lib檔案時呼叫.dll中的函式稍微麻煩些。另外,Windows下也可以由.dll檔案得到相應的.lib檔案。 參見http://www.oschina.net/question/234345_48496

那為什麼在Linux下用GCC生成和使用.so檔案時不需要類似.lib匯入庫這樣的東西呢?直接原因是Windows下的連結器只能處理.lib這樣的非可執行檔案,不能處理.dll這樣的可執行檔案,所以用一個匯入庫(.lib)來輔助連結; 而在Linux下,.so檔案是elf格式的,這種格式既可執行又能連結,所以GCC就沒必要使用額外的檔案來輔助連結共享庫了。網上有人對Windows下匯入庫的概念給出了更深層一點的解釋: DLL中匯出的符號名未必是應用程式使用它時匯入的符號名;為了方便得到對語言中立的元件,微軟特意採用了現在的方案:在DLL裡匯出一套符號,然後通過DEF檔案或”Import Library”來使用另一套符號進行匯入,這樣就相當於多了一層轉換,可兼顧同語言和跨語言的應用。 這也是有道理的。

轉:http://blog.shengbin.me/posts/windows-dll-with-lib/

相關推薦

為何Windows動態伴隨一個靜態

今天同學來問了一個問題:Visual Studio中生成的動態庫總是伴隨著一個靜態庫檔案,我把這兩個檔案同樣進行重新命名之後還能不能使用? 我對VS下的動態庫的生成並不是很熟悉,表示無法回答這個問題。但這個問題本身卻也讓我產生了疑問:動態庫真的需要總是伴隨著一個靜態庫?根據我在Linux下的經驗,這兩種形式

windows 、linux 多個靜態合併成一個靜態

第一步、 開啟visual studio 下的對應平臺命令列工具 第二步、 執行lib命令 lib /OUT:ETKey.lib A.lib B.lib ,完畢 linux 下的合成庫 Li

連結一個靜態到另一個靜態

問題:有兩個靜態庫a.lib和b.lib,靜態庫x.lib使用a.lib和b.lib,x.lib相當於提供了一個輸出庫,應用程式app.exe使用x.lib。那麼,應用程式app當然需要連線到靜態庫x.lib,但它是否還需要連線到a.lib和b.lib? 解答:根據實驗,a

windows動態dll和靜態編譯和使用問題

window下動態庫dll和靜態庫lib問題 windows下動態庫dll和靜態庫lib的聯絡和區別,以及示例匯出個動態庫 https://blog.csdn.net/lifei092/article/details/79630273 問題: 1,生成dll時,同時生成lib是做

為何windows用cmake編譯找不到Boost

問題描述:        CMake Error at D:/CMake/CMake 2.8/share/cmake-2.8/Modules/FindBoost.cmake:910 (message):        Unable to find the requeste

windows系統可執行程式呼叫lib靜態和dll動態的方法

#include <stdio.h> #include <Windows.h>   int main() {    HINSTANCE h=LoadLibraryA("newdll.dll");     typedef int (* FunPtr)(int a,int b);//定義函

gcc和MinGW的異同(在cygwin/gcc做的東西可以無縫的用在linux,沒有任何問題,是在windows開發linux程序的一個很好的選擇)

實現 o-c tool 交叉 lin 分析 模擬 gcc編譯器 還要 cygwin/gcc和MinGW都是gcc在windows下的編譯環境,但是它們有什麽區別,在實際工作中如何選擇這兩種編譯器。 cygwin/gcc完全可以和在linux下的gcc化做等號,這個可以從bo

如何理解Linux動態概念,和靜態概念,通俗易懂的解釋如下:

動態庫和靜態庫都是一組函式集合,打包在一起供應用程式呼叫,區別是: 靜態庫名稱一般為xxx.a,在編譯時和應用程式連結在一起,這樣的應用程式佔用空間較大。 動態庫名稱一般為xxx.so,對於動態庫即可以在編譯時連結,也可以使用dlopen()/dlsy

WindowsPython(anaconda環境)第三方OpenCV安裝

啟動jupyter notebook可以直接開啟anaconda navigator,點選launch,更為簡便的方法是開啟anaconda prompt,輸入jupyter notebook jupyter notebook啟動後,其工作目錄只能位於起始目錄和起始

【Python】Windows用Jieba分詞和WordCloud生成中文詞雲

一、開啟Anaconda Prompt,用activate命令啟用環境 二、從清華映象下載所需庫: jieba分詞庫 wordcloud繪製詞雲庫 numpy常用於處理陣列 PIL為影象處理標準庫 pip install jieba -i https://pypi

windows 利用Anaconda安裝python及其第三方

安裝python--簡易方法為什麼安裝Anaconda因為python的第三庫的安裝比較繁瑣,其是第三方庫較多且存在各種包的相容問題,而Anaconda集成了python所需的第三方庫,其將python經常使用的第三庫的包打包,進行包管理和下載比較方便。安裝步驟先安裝Anac

Ubuntu--(5)LinuxC++編譯生成自定義靜態/動態

編譯生成靜態庫: 1.編寫CPP檔案test.h #include <iostream> using namespace std; class ADD_SUB{ public

Windows使用命令安裝Python的scipy出錯的解決

平時使用Python都是在Sublime下使用,不想使用IDE。使用各種庫時安裝也就是使用pip安裝即可。來說說今天自己遇到的一個問題:使用scipy數學庫時,使用命令: pip install scipy 後,顯示正常的下載,然後是一串的文字,最後一串紅色的報錯警告(我不

windows 安裝composer並下載第三方類(設定環境變數path)

第一步 第二步 第三步 第四步 將變數值複製到編輯器裡 如下: C:\Program Files\Python36\Scripts\;C:\Program Files\Python36\;%SystemRoot%\system32;%SystemRo

打包生成一個靜態&動態

靜態庫和動態庫之間不同之處就在於程式碼被載入的時刻不同。靜態庫的程式碼在編譯過程中已經被載入可執行程式,因此體積比較大;動態庫(共享庫)的程式碼是在可執行程式執行時被載入記憶體的,在編譯過程中僅簡單的引用,因此程式碼體積較小 一、靜態庫和動態庫的定義

Windows對硬體埠的操作---WinIo的使用

本文參考了網上的一篇文章“VC 2010下WinIo 3.0直接訪問I/O埠”; 由於Windows的核心保護機制,我們無法直接對通過核心操作硬體,通過使用WinIo可以繞過這一限制,實現對Windows硬體埠或者地址的直接操作。實際操作中發現WinIo庫既可以對普通的I/O埠進行操作,也可以對GPIO進行操

windows的使用別人編譯好的檔案進行安裝xgboost

(0)前提是,你得下載好anaconda,並且安裝之,我的下載地址如下(python3 windows 64位) https://repo.continuum.io/archive/Anaconda3-4.4.0-Windows-x86_64.exe (1)下載xgboos

Linuxgcc編譯器生成和使用靜態動態學習筆記

我們通常把一些公用函式製作成函式庫,供其它程式使用。函式庫分為靜態庫和動態庫兩種。靜態庫在程式編譯時會被連結並拷貝到目的碼中,程式執行時將不再需要該靜態庫。動態庫在程式編譯時並不會被拷貝到目的碼中,而是在程式執行時才被載入,因此在程式執行時還需要動態庫存在。本質上說庫是一

Linux簡單編譯so,呼叫另一個so的方法

linux下將c/c++編譯成so庫 gcc -fPIC -shared Cat.c -o libcat.so -fPIC是壓制警告 -shared是生成動態庫 Cat.c是要編譯的檔案 -o是要生成的檔案的名稱 linux下將c/c++生成可執行檔

Windows無法使用Nginx作為一個http檔案伺服器(許可權問題?)

這裡使用的Nginx版本來自於最新的OpenResty。 nginx.conf: server { listen 8000; server_name chenzx alias chenzx.localhost;