c編譯鏈接靜態庫
C語言編輯的作用是檢查語法,製作C語言的源文件和頭文件,生成匯編代碼。
C語言編輯的作用是將匯編代碼轉換機器碼。在這一步中,會對文件內部的語法語義做處理,如果編譯出錯,無法進行後續動作。
C語言鏈接的作用是將機器碼鏈接到一起生成可執行程序。這一步會對文件之間的關聯做檢查,如果出錯,將不會生成可執行程序,也就無法執行。
(1)c編譯鏈接靜態庫擴展閱讀:
C語言鏈接時,將源文件中用到的庫函數與匯編生成的目標文件.o合並生成可執行文件。該可執行文件會變大很多,一般是調用自己電腦上的靜態庫。
靜態庫和應用程序編譯在一起,在任何情況下都能運行,而動態庫是動態鏈接,文件生效時才會調用。很多代碼編譯通過,鏈接失敗就極有可能在靜態庫和動態庫這出現了紕漏,要視情況解決。缺少相關所需文件,就會鏈接報錯。這個時候就要檢查下本地的鏈接庫是不是缺損。
2. C語言vs怎麼使用自己做的靜態庫與動態庫,本人小白,請求詳解
1.靜態鏈接庫
打開VS2010,新建一個項目,選擇win32項目,點擊確定,選擇靜態庫這個選項,預編譯頭文件可選可不選。
在這個空項目中,添加一個.h文件和一個.cpp文件。名字我們起為static.h和static.cpp
static.h文件:
[cpp]view plain
#ifndefLIB_H
#defineLIB_H
extern"C"intsum(inta,intb);
#endif
- static.cpp文件:
#include"static.h"
intsum(inta,intb)
{
returna+b;
}
- 編譯這個項目之後,會在debug文件夾下生成static.lib文件,這個就是我們需要的靜態鏈接庫。
#include<stdio.h>
#include<stdlib.h>
#include"static.h"
#pragmacomment(lib,"static.lib")
intmain()
{
printf("%d ",sum(1,2));
system("pause");
return0;
}
- 編譯運行可得結果:3
#ifndefDYNAMIC
#defineDYNAMIC
extern"C"__declspec(dllexport)intsum(inta,intb);
#endifDYNAMIC
#include"dynamic.h"
intsum(inta,intb)
{
returna+b;
}
- 編譯這個項目,會在debug文件夾下生成dynamic.dll文件。
#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
#include"dynamic.h"
intmain()
{
HINSTANCEhDll=NULL;
typedefint(*PSUM)(inta,intb);
PSUMpSum;
hDll=LoadLibrary(L"dynamic.dll");
pSum=(PSUM)GetProcAddress(hDll,"sum");
printf("%d ",pSum(1,2));
system("pause");
FreeLibrary(hDll);
return0;
}
- 編譯運行結果為:3
[cpp]view plain
下面說明如何調用靜態鏈接庫。
首先需要新建一個空項目,起名為test。將之前static項目下的static.h和static.lib這個2個文件復制到test項目的目錄下,並在工程中加入static.h文件。
新建一個test.cpp文件如下:
[cpp]view plain
#pragma comment(lib,"static.lib"),這一句是顯式的導入靜態鏈接庫。除此之外,還有其他的方法,比如通過設置路徑等等,這里不做介紹。
2.動態鏈接庫
和創建靜態鏈接庫一樣,需要創建一個空的win32項目,選擇dll選項。創建dynamic.cpp和dynamic.h文件
dynamic.h文件:
[cpp]view plain
dynamic.cpp文件:
[cpp]view plain
下面介紹如何調用動態鏈接庫,這里講的是顯式的調用。
在剛才的test項目下,把static.lib和static.h文件刪除,把dynamic.h和dynamic.dll復制到該目錄下,並在項目中添加dynamic.h文件,修改test.cpp文件為:
[cpp]view plain
特別提示:
1.extern "C"中的C是大寫,不是小寫
2.如果從VS2010中直接運行程序,lib和dll需要放到test項目的目錄下;如果想雙擊項目test下的debug文件中的exe文件直接運行的話,需把lib和dll放入debug文件夾下。
3. linux怎樣實現c語言動態庫與靜態庫的鏈接
Linux系統中靜態庫是.a文件,編譯鏈接.a文件只需要加上.a文件的完整的文件路徑就可以了,比如:
gcc -o hello hello.c /usr/lib/libm.a
Linux系統的動態庫是系統中的.so文件,編譯鏈接動態庫需要用-L參數指定動態庫的搜索路徑,還要用-l(這個是小寫的L)指定動態庫的名字,比如:
gcc -o hello hello.c -L/usr/openssl/lib -lcrypto
4. 如何編譯C/Fortran動態/靜態鏈接庫
首先,傳統的編譯,也就是靜態編譯是把 源文件 翻譯成目標文件,這個是一次性過程,也就是你所謂的靜態編譯。
後來的Java和.NET等語言,首先編譯成中間形式,然後運行過程中根據需要編譯成本地代碼(注意這個過程不是一次性的,下次運行重新編譯),這個就是JIT(即時編譯)技術,從即時編譯發展出了動態編譯技術
————————————
(傳統的)編譯完成後,像C/C++、Fortran、匯編等語言,可以把多個目標文件合並到一個庫文件中,這個就是靜態庫。比如常說的庫函數printf就是libc裡面的函數。
如果有了啟動函數(main),main裡面使用了printf,就可以通過靜態鏈接技術,從libc中提取出printf所在的文件加入到可執行文件中,如果printf還需要其它函數,就繼續搜索並加入列表,直到形成一個閉包。這個就是靜態鏈接。
可是靜態鏈接有個明顯的缺點,如果每個程序都需要printf,那麼printf這個函數的代碼就會同時存在在每個程序中,這樣也太佔地方了吧。所以發明了動態連接技術,其實有兩種形式。無論哪一種,都是首先記錄下需要調用printf這個函數以及所在的動態庫,等到運行的時候再載入動態庫,從動態庫中找到真正的printf去執行。
由於,動態鏈接技術需要一些額外的信息,傳統的靜態庫是不具備的,這些額外信息主要是重復載入和卸載時所需要的一些代碼,因此需要動態鏈接庫。
5. linux怎樣實現c語言動態庫與靜態庫的鏈接
Linux系統中靜態庫是.a文件,編譯鏈接.a文件只需要加上.a文件的完整的文件路徑就可以了,比如:
gcc
-o
hello
hello.c
/usr/lib/libm.a
Linux系統的動態庫是系統中的.so文件,編譯鏈接動態庫需要用-L參數指定動態庫的搜索路徑,還要用-l(這個是小寫的L)指定動態庫的名字,比如:
gcc
-o
hello
hello.c
-L/usr/openssl/lib
-lcrypto
6. 靜態庫如何鏈接靜態庫
在工程搭建時,可能會有將靜態庫鏈接成動態庫的需求,如出於代碼保護的角度,某些模塊會發布.a擴展名的靜態庫,我們要將多個這樣的靜態庫鏈接成一個動態庫。但與直接link目標文件不同的是,ld以默認參數執行時,並把靜態庫中沒有用到的函數過濾掉,導致生成的so並未包含所要的函數,因此要加上--whole-archive參數,以保證所有的函數都包含在生成的so中。
在使用cmake時,CMakeLists.txt的寫法如下:
add_library(
${MODULE_NAME}
SHARED
${CMAKE_SOURCE_DIR}/builttime.c #要生成一個so,至少要包含一個源文件,實在沒有可以把庫的編譯時間戳打到這兒。
)
target_link_libraries(
${MODULE_NAME}
${${MODULE_NAME}_EXTRA_LDFLAGS}
"-Wl,--whole-archive" #告訴編譯器,從這里開始,所有的庫的內容都包含到so中
${LOCAL_MODULES} #可以是以源代碼生成的靜態庫
${PREBUILT_MODULES} #可以是預先生成的靜態庫
"-Wl,--no-whole-archive" #告訴編譯器,從這里開始,以後的庫的內容不用都包含到so中
)
7. C語言編譯問題 靜態鏈接
鏈接靜態庫的意思就是在編譯階段需要將靜態庫鏈接到工程中,這樣在編譯時程序才不會出錯,在用到靜態庫的函數時能夠找到函數的實現,如果沒有鏈接靜態庫則編譯時會報錯。
這里需要區分的就是鏈接動態庫與靜態庫的區別,你可以到網上找一些資料看看。
而且鏈接靜態庫是將整個庫文件都導入到了工程中,所以會增加工程的大小。
8. 如何使用cmake生成基於靜態庫的動態鏈接庫
在工程搭建時,可能會有將靜態庫鏈接成動態庫的需求,如出於代碼保護的角度,某些模塊會發布.a擴展名的靜態庫,我們要將多個這樣的靜態庫鏈接成一個動態庫。但與直接link目標文件不同的是,ld以默認參數執行時,並把靜態庫中沒有用到的函數過濾掉,導致生成的so並未包含所要的函數,因此要加上--whole-archive參數,以保證所有的函數都包含在生成的so中。 在使用cmake時,CMakeLists.txt的寫法如下: add_library( ${MODULE_NAME} SHARED ${CMAKE_SOURCE_DIR}/builttime.c #要生成一個so,至少要包含一個源文件,實在沒有可以把庫的編譯時間戳打到這兒。 ) target_link_libraries( ${MODULE_NAME} ${${MODULE_NAME}_EXTRA_LDFLAGS} "-Wl,--whole-archive" #告訴編譯器,從這里開始,所有的庫的內容都包含到so中 ${LOCAL_MODULES} #可以是以源代碼生成的靜態庫 ${PREBUILT_MODULES} #可以是預先生成的靜態庫 "-Wl,--no-whole-archive" #告訴編譯器,從這里開始,以後的庫的內容不用都包含到so中 )
9. C 創建靜態庫鏈接.網問題,怎麼解決
(1)VC++6.0環境
第一步:NEW->Projects->Win32 Static Library
第二步:編寫頭文件和.cpp源文件。
第三步:將頭文件和.cpp源文件添加到剛才新建的工程中。如果你用的是VC6.0可能會下面的問題。(對於這個問題,下面會有一篇文章來解決。文章地址:
VRQNWV0C5($Z$$Y[EIZL_Z4
第四步:編譯、鏈接就可以生成一個後綴為.lib文件。也就是說靜態庫就生成好了。
(2)DEV C++環境
第一步:NEW->Project->Static Library
第二步:編寫頭文件和.cpp源文件。
第三步:將頭文件和.cpp源文件添加到剛才新建的工程中。
第四步:編譯、鏈接就可以生成一個後綴為.a文件。(應為DEV C++是基於GCC的,所以生成的靜態庫文件是以.a結尾的。)
小結:其實創建靜態庫的過程,都是類似的。
如何使用靜態庫?
(1)在VC6.0和DEV C++中通用的方法(對於後綴是.lib文件):
使用預編譯語句。如:#pragma comment(lib, "庫文件名")
並且要將頭文件在程序的開始出聲明。
例子:
#include #include #include "Max_Value.h" #pragma comment(lib, "Max_Value.lib")
using namespace std;
int main(int argc, char *argv[]) { int a[3]={2,3,4}; int i; printf("hello! "); i=Find_max(a,3); printf("%d ",i); system("PAUSE"); return 0; }
庫文件在最後貼出來。
(2)在dev C++ 中使用.a靜態庫文件
首先要創建一個工程,然後Project->Project Options->Parameters,點擊Add library or Object,選擇你要使用的那個庫文件。這個時候就隨便你什麼後綴的庫文件了。
庫文件具體的源代碼如下:
//Max_Value.h
#ifndef _MAX_VALUE_H #define _MAX_VALUE_H int Find_max(int *a, int n); #endif
//Max_Value.cpp
int Find_max(int *a ,int n ) { int max; int i; max=a[0]; for(i=1;i if(a[i]>max) max=a[i]; } return max; }
10. C語言編輯編譯連接的作用是什麼
C語言編輯的作用是檢查語法,製作C語言的源文件和頭文件,生成匯編代碼。
C語言編輯的作用是將匯編代碼轉換機器碼。在這一步中,會對文件內部的語法語義做處理,如果編譯出錯,無法進行後續動作。
C語言鏈接的作用是將機器碼鏈接到一起生成可執行程序。這一步會對文件之間的關聯做檢查,如果出錯,將不會生成可執行程序,也就無法執行。
(10)c編譯鏈接靜態庫擴展閱讀:
C語言鏈接時,將源文件中用到的庫函數與匯編生成的目標文件.o合並生成可執行文件。該可執行文件會變大很多,一般是調用自己電腦上的靜態庫。
靜態庫和應用程序編譯在一起,在任何情況下都能運行,而動態庫是動態鏈接,文件生效時才會調用。很多代碼編譯通過,鏈接失敗就極有可能在靜態庫和動態庫這出現了紕漏,要視情況解決。缺少相關所需文件,就會鏈接報錯。這個時候就要檢查下本地的鏈接庫是不是缺損。