導航:首頁 > 源碼編譯 > 編譯動態庫引用哪些外部庫

編譯動態庫引用哪些外部庫

發布時間:2022-09-03 06:27:50

1. gcc頭文件包含,動態鏈接庫

1、包含哪個頭文件,需要查詢程序使用庫的SDK說明文檔,比如printf(),它的函數聲明在stdio.h頭文件中,因此要使用printf(),必須在開頭加上一句:
#include <stdio.h>
2、動態鏈接庫,這個是從靜態鏈接庫發展而來的,所謂庫即很多程序都會使用的代碼,因此程序員提取出來,稱之為庫,最早的庫是靜態庫,所謂靜態即表示在生成可執行文件的鏈接階斷,鏈接器會將程序所需要的庫文件,和程序的文件一起打包為一個文件。這會使得應用程序很大,不僅不利於存儲而且操作系統載入時也會耗費時間,因此才引入了動態庫,動態庫只會在鏈接階斷生成程序時,加入一小段數據,用於描述此程序使用了哪此庫,使用了庫中的哪些函數,以及這些函數的虛擬內存地址。

2. VC程序調用動態庫,編譯時候也跟著編譯動態庫

不太清楚你的工程是如何建立的,想必一個工程是生成動態鏈接庫,另一個是調用程序EXE了。由於VC動態庫有兩種形式,Regular和Extended兩種,其中一種能導出類,另一種只能導出變數和函數。如果導出的是類,你在編譯EXE文件時自然需要用到類得聲明文件,即你前面所說的動態庫本身所引用的文件。如果導出的是函數或變數,有可能出現的情況是:一般為了代碼的重用性,把需要導出的函數或變數單獨放在一個頭文件中,用一個宏控制其導入、導出。編譯動態庫時,宏定義為導出,編譯EXE時,宏變為導入,這個頭文件為兩者共用。如果不小心在這個頭文件中包含了其他頭文件,也可能出現你說的情況。如果動態庫調用直接採用函數入口地址的方法,則什麼都不用聲明,當然,只適用於導出函數與變數的情形。

3. 如何編譯動態庫,該動態庫需要鏈接另外一個動態庫

看你的makefile, 猜測是沒有指定動態庫頭文件的路徑. -I編譯參數來指定

4. 我在一個機器上編了個動態庫,在另一個機器上編譯了一個引用這個動態庫的可執行程序,能調用不

什麼語言?C++還是C#?Native還是managed?

一般是沒有問題的,只要保證:
1、你這個動態庫沒有依賴其他動態庫(包括系統的、MFC的、CRT的、VC的、或者.NET Framework的),或者依賴的其他動態庫在另一台機器上也都有;
2、而且不存在32位和64位的兼容問題(即動態庫以及可執行程序都是32位的或者都是64位的,而且操作系統也不存在這個兼容性的差異);
3、可執行程序連接動態庫使用的LIB文件和動態庫是匹配的(如果是native的)

____________________
補充:

哦~~~ Linux我是門外漢了,那就看看其他朋友有沒有Linux大拿幫忙回答一下吧……

5. 如何在vc中使用mingw編譯出來的動態庫和靜態庫

mingw編譯出來的靜態庫後綴名為.a,編譯出來的動態庫的導入庫後綴名為.dll.a,而在windows下後綴名為.lib的庫可能是靜態庫也可能是動態庫的導入庫。

mingw編譯出來的動態庫的導入庫可以直接在vc中直接使用,例如

#pragma comment(lib, "libx264.dll.a")

這樣你就不需要生成一個.lib後綴的動態庫的導入庫了,網上也有如何從.dll生成.lib的方法。

如果鏈接了動態庫的導入庫libpthread.dll.a,你發布的應用程序就要帶上pthread的dll。
使用靜態庫的好處是發布的應用程序組件模塊里不需要帶上相關的dll,如果要使用mingw編譯出來的靜態庫,可以如下:

#pragma comment(lib, "libx264.a")

但是僅僅鏈接這么一個靜態庫是不夠的,你還需要鏈接

libgcc.a

libmingwex.a

你可能還需要鏈接libmsvcrt.a

否則會報一堆錯誤:error LNK2001: 無法解析的外部符號

上面的這些庫在C:\MinGW\lib目錄或子目錄下面可以找到。

鏈接這些庫的原因是mingw使用的gcc編譯器和vc編譯器之間存在差異

6. 動態庫的編譯


生成動態連接庫,假設名稱為libtest.so
gcc x.cy.cz.c-fPIC-shared-olibtest.so
將main.c和動態連接庫進行連接生成可執行文件
gcc main.c-L.-ltest-omain
輸出LD_LIBRARY_PATH環境變數,以便動態庫裝載器能夠找到需要的動態庫
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
測試是否動態連接,如果列出libtest.so,那麼應該是連接正常了
ldd main

7. 三:構建靜態庫與動態庫 及 如何使用外部共享庫和頭

我們通常把一些公用函數製作成函數庫,供其它程序使用。

函數庫分為靜態庫和動態庫兩種。

靜態庫在程序編譯時會被連接到目標代碼中,程序運行時將不再需要該靜態庫。

動態庫在程序編譯時並不會被連接到目標代碼中,而是在程序運行是才被載入,因此在程序運行時還需要動態庫存在。

本文主要通過舉例來說明在Linux中如何創建靜態庫和動態庫,以及使用它們。

在創建函數庫前,我們先來准備舉例用的源程序,並將函數庫的源程序編譯成.o文件。

第1步:編輯得到舉例的程序--hello.h、hello.c和main.c;

hello.h(見程序1)為該函數庫的頭文件。

hello.c(見程序2)是函數庫的源程序,其中包含公用函數hello,該函數將在屏幕上輸出"Hello XXX!"。

main.c(見程序3)為測試庫文件的主程序,在主程序中調用了公用函數hello。

程序1: hello.h

#ifndef HELLO_H

#define HELLO_H

void hello(const char *name);

#endif //HELLO_H

程序2: hello.c

#include

void hello(const char *name)

{

printf("Hello %s!/n", name);

}

程序3: main.c

#include "hello.h"

int main()

{

hello("everyone");

return 0;

}

第2步:將hello.c編譯成.o文件;

無論靜態庫,還是動態庫,都是由.o文件創建的。因此,我們必須將源程序hello.c通過gcc先編譯成.o文件。

在系統提示符下鍵入以下命令得到hello.o文件。

# gcc -c hello.c

#

(注1:本文不介紹各命令使用和其參數功能,若希望詳細了解它們,請參考其他文檔。)

(注2:首字元"#"是系統提示符,不需要鍵入,下文相同。)

我們運行ls命令看看是否生存了hello.o文件。

# ls

hello.c hello.h hello.o main.c

#

(注3:首字元不是"#"為系統運行結果,下文相同。)

在ls命令結果中,我們看到了hello.o文件,本步操作完成。

下面我們先來看看如何創建靜態庫,以及使用它。

第3步:由.o文件創建靜態庫;

靜態庫文件名的命名規范是以lib為前綴,緊接著跟靜態庫名,擴展名為.a。例如:我們將創建的靜態庫名為myhello,則靜態庫文件名就是libmyhello.a。在創建和使用靜態庫時,需要注意這點。創建靜態庫用ar命令。

在系統提示符下鍵入以下命令將創建靜態庫文件libmyhello.a。

# ar cr libmyhello.a hello.o

#

我們同樣運行ls命令查看結果:

# ls

hello.c hello.h hello.o libmyhello.a main.c

#

ls命令結果中有libmyhello.a。

第4步:在程序中使用靜態庫;

靜態庫製作完了,如何使用它內部的函數呢?只需要在使用到這些公用函數的源程序中包含這些公用函數的原型聲明,然後在用gcc命令生成目標文件時指明靜態庫名,gcc將會從靜態庫中將公用函數連接到目標文件中。注意,gcc會在靜態庫名前加上前綴lib,然後追加擴展名.a得到的靜態庫文件名來查找靜態庫文件。

在程序3:main.c中,我們包含了靜態庫的頭文件hello.h,然後在主程序main中直接調用公用函數hello。下面先生成目標程序hello,然後運行hello程序看看結果如何。

# gcc -o hello main.c -L. -lmyhello

# ./hello

Hello everyone!

#

我們刪除靜態庫文件試試公用函數hello是否真的連接到目標文件 hello中了。

# rm libmyhello.a

rm: remove regular file `libmyhello.a'? y

# ./hello

Hello everyone!

#

程序照常運行,靜態庫中的公用函數已經連接到目標文件中了。

我們繼續看看如何在Linux中創建動態庫。我們還是從.o文件開始。

第5步:由.o文件創建動態庫文件;

動態庫文件名命名規范和靜態庫文件名命名規范類似,也是在動態庫名增加前綴lib,但其文件擴展名為.so。例如:我們將創建的動態庫名為myhello,則動態庫文件名就是libmyhello.so。用gcc來創建動態庫。

在系統提示符下鍵入以下命令得到動態庫文件libmyhello.so。

# gcc -shared -fPCI -o libmyhello.so hello.o

#

我們照樣使用ls命令看看動態庫文件是否生成。

# ls

hello.c hello.h hello.o libmyhello.so main.c

#

第6步:在程序中使用動態庫;

在程序中使用動態庫和使用靜態庫完全一樣,也是在使用到這些公用函數的源程序中包含這些公用函數的原型聲明,然後在用gcc命令生成目標文件時指明動態庫名進行編譯。我們先運行gcc命令生成目標文件,再運行它看看結果。

# gcc -o hello main.c -L. -lmyhello

# ./hello

./hello: error while loading shared libraries: libmyhello.so: cannot open shared object file: No such file or directory

#

哦!出錯了。快看看錯誤提示,原來是找不到動態庫文件libmyhello.so。程序在運行時,會在/usr/lib和/lib等目錄中查找需要的動態庫文件。若找到,則載入動態庫,否則將提示類似上述錯誤而終止程序運行。我們將文件 libmyhello.so復制到目錄/usr/lib中,再試試。

# mv libmyhello.so /usr/lib

# ./hello

Hello everyone!

#

成功了。這也進一步說明了動態庫在程序運行時是需要的。

我們回過頭看看,發現使用靜態庫和使用動態庫編譯成目標程序使用的gcc命令完全一樣,那當靜態庫和動態庫同名時,gcc命令會使用哪個庫文件呢?抱著對問題必究到底的心情,來試試看。

先刪除 除.c和.h外的 所有文件,恢復成我們剛剛編輯完舉常式序狀態。

# rm -f hello hello.o /usr/lib/libmyhello.so

# ls

hello.c hello.h main.c

#

在來創建靜態庫文件libmyhello.a和動態庫文件libmyhello.so。

# gcc -c hello.c

# ar cr libmyhello.a hello.o

# gcc -shared -fPCI -o libmyhello.so hello.o

# ls

hello.c hello.h hello.o libmyhello.a libmyhello.so main.c

#

通過上述最後一條ls命令,可以發現靜態庫文件libmyhello.a和動態庫文件libmyhello.so都已經生成,並都在當前目錄中。然後,我們運行gcc命令來使用函數庫myhello生成目標文件hello,並運行程序 hello。

# gcc -o hello main.c -L. -lmyhello

# ./hello

./hello: error while loading shared libraries: libmyhello.so: cannot open shared object file: No such file or directory

#

從程序hello運行的結果中很容易知道,當靜態庫和動態庫同名時, gcc命令將優先使用動態庫。

8. 什麼叫靜態庫和動態庫

兩者區別:
一,靜態庫的使用需要:
1
包含一個對應的頭文件告知編譯器lib文件裡面的具體內容
2
設置lib文件允許編譯器去查找已經編譯好的二進制代碼
二,動態庫的使用:
程序運行時需要載入動態庫,對動態庫有依賴性,需要手動加入動態庫
三,依賴性:
靜態鏈接表示靜態性,在編譯鏈接之後,
lib庫中需要的資源已經在可執行程序中了,
也就是靜態存在,沒有依賴性了
動態,就是實時性,在運行的時候載入需要的資源,那麼必須在運行的時候提供
需要的
動態庫,有依賴性,
運行時候沒有找到庫就不能運行了
四,區別:
簡單講,靜態庫就是直接將需要的代碼連接進可執行程序;動態庫就是在需要調用其中的函數時,根據函數映射表找到該函數然後調入堆棧執行。
做成靜態庫可執行文件本身比較大,但不必附帶動態庫
做成動態庫可執行文件本身比較小,但需要附帶動態庫
五:
首先糾正所謂「靜態連接就是把需要的庫函數放進你的exe之中」的說法。在真實世界中,有三個概念:use
static
libary,
static
linked
dll,
dynamic
linked
dll.
多數人混淆了static
libary

static
linked
dll的概念,當然他們有似是而非的「相似之處」,比如都用到.lib,下面具體說明。
使用靜態庫(use
static
libary)是把.lib和其他.obj一起build在目標文件中,目標文件可以是.exe,也可以是.dll或.oxc等。一般情況下,可以根本就沒有「對應的」.dll
文件,如c
run
time(crt)庫。一個例子就是,寫一個main(){},build出來並不是只有幾個位元組,當然有人會說那還有exe文件頭呢?是,即使加上文件頭的尺寸,build出的執行文件仍然「莫名的大」。實際上那多出來的部分就是crt靜態庫。姑且可以把靜態庫.lib理解成外部程序的obj文件比較合理,它包含了函數的實現。

9. 如何讓自己的程序動態引用debug和release的庫

本文所描述的動態庫是基於MFC的。IDE是VS2005. 默認情況下,如果一個動態庫工程名叫A,動態庫的名稱將是A.lib A.dll A.def。不管工程是release下還是debug下。這就導致一個問題。如果我在另一個工程中使用這個動態庫,這個工程在release下應該鏈接release下的相應庫文件,這個工程在debug下應該鏈接debug下的相應庫文件。於是乎,可能需要來回拷貝覆蓋。甚是麻煩。為什麼我們的動態庫工程不能像OpenCV那樣,debug就將默認生成的庫名由默認的A.lib A.dll換成Ad.lib和Ad.dll呢?如果這能實現,我們在使用這些庫的工程中的"項目"->"屬性"->"鏈接器"->"輸入"->"附加依賴庫"裡面分別設置不就OK了嗎。 修改動態庫名稱的方法如下:(1) 打開動態庫工程,設置DEBUG模式,然後選擇"項目"->"屬性"->"鏈接器"->"常規"->"輸出文件",一般在文件名後附加 'd'即可。(2) 選擇"項目"->"屬性"->"鏈接器"->"高級"->"導入庫",一般在文件名後附加 'd'即可。(3) 選擇"項目"->"屬性"->"鏈接器"->"輸入"->"模塊定義文件",一般在文件名後附加 'd'即可。注意:這里是需要一個模塊定義文件,工程下默認只有 "工程名.def" 文件,需要將該文件復制一份,然後修改其中LIBRARY 後面引號中的內容加一個d。如; ListCtrlEx.def : Declares the mole parameters for the DLL.LIBRARY "ListCtrlEx" DESCRIPTION 'ListCtrlEx Windows Dynamic Link Library'EXPORTS ; Explicit exports can go here 修改後為:; ListCtrlEx.def : Declares the mole parameters for the DLL.LIBRARY "ListCtrlExd" ; Explicit exports can go here 如果不做這一步,在編譯動態庫時會出現如下警告 (4) release的個人認為無需改變。這樣選擇菜單"生成"->"批生成"生成debug和release版本的庫。 ////////////////////////////////////////////////////////////////////////////////////////////////////////////// 到這里我們大概完成了任務的80%。接下來就像使用很多開源軟體包一樣,設置我們自己的工程。(1) 選擇"項目"->"選項"->"項目和解決方案"->"C++目錄",選擇庫文件,然後將剛剛生成的debug和release版本的庫的路徑填入。

閱讀全文

與編譯動態庫引用哪些外部庫相關的資料

熱點內容
卡爾曼濾波演算法書籍 瀏覽:769
安卓手機怎麼用愛思助手傳文件進蘋果手機上 瀏覽:844
安卓怎麼下載60秒生存 瀏覽:803
外向式文件夾 瀏覽:240
dospdf 瀏覽:431
怎麼修改騰訊雲伺服器ip 瀏覽:392
pdftoeps 瀏覽:496
為什麼鴻蒙那麼像安卓 瀏覽:736
安卓手機怎麼拍自媒體視頻 瀏覽:186
單片機各個中斷的初始化 瀏覽:724
python怎麼集合元素 瀏覽:481
python逐條解讀 瀏覽:833
基於單片機的濕度控制 瀏覽:499
ios如何使用安卓的帳號 瀏覽:883
程序員公園采訪 瀏覽:812
程序員實戰教程要多長時間 瀏覽:979
企業數據加密技巧 瀏覽:135
租雲伺服器開發 瀏覽:814
程序員告白媽媽不同意 瀏覽:337
攻城掠地怎麼查看伺服器 瀏覽:601