linux簡單實現靜態鏈結和動態鏈結

2021-08-15 19:22:26 字數 4585 閱讀 4196

在給別人傳送檔案的時候,如果我們只想讓別人呼叫功能而已,不想自己的源**公布出去,我們可以選擇將檔案做成乙個庫,直接供別人呼叫就可以了。

這樣的話,在網路上分享自己的勞動成果的話,只要傳送乙個鏈結庫和對應的標頭檔案(.h)就足以(前提是確保**已經千錘百鍊過,不然除了問題別人沒辦法解決) 。

靜態庫和動態庫

static靜態庫  :一般名字是lib***.a;

shared動態庫:一般名字是lib***.so;

windows下:.dll檔案

靜態庫製作:

[yan@localhost c_work]$ gcc -c file1.c

//生成乙個file.o的檔案

[yan@localhost c_work]$ gcc -c file2.c

[yan@localhost c_work]$ ar -rcs libname.a file1.o file2.o ...

//打包生成乙個libname.a的靜態庫

//-r:replace,當插入的模組已經存在,則替換同名模組;若不存在,返回乙個錯誤;預設新增加的在檔案尾。

//-c:create

//-s:static

動態庫製作:

[yan@localhost c_work]$ gcc -shared -fpic -o libname.so file1.c file2.c ...

//生成乙個libname.so的動態庫

//-shared:生成動態庫

//-fpic:產生**位置無關於**

靜態庫製作示例

[yan@localhost src]$ cat add.c

#include

int add(int a,int b)

/* ----- end of add()  ----- *

[yan@localhost src]$ cat sub.c

#include

int sub(int a,int b)

/* ----- end of sub()  ----- *

[yan@localhost src]$ cat add.c

#include

intmul(int a,int b)

/* ----- end of

mul()  ----- *

[yan@localhost src]$ cat fun.h

#ifndef __fun_h_

#define __fun_h_

extern add(int a,int b);

extern sub(int a,int b);

extern mul(int a,int b);

#endif

[yan@localhost src]$ cat main.c

#include

#include

int main (int argc, char **argv)

/* ----- end of main() ----- */

//生成靜態庫

[yan@localhost src]$ ls

add.c  fun.h  main.c  mul.c  sub.c

[yan@localhost src]$

gcc -c *.c

main.c:1:17: error: fun.h: no such file or directory

[yan@localhost src]$ ls

add.c  add.o  fun.h  main.c  mul.c  mul.o  sub.c  sub.o

[yan@localhost src]$

ar -rcs libfun.a *.o

[yan@localhost src]$ ls

add.c  add.o  fun.h  

libfun.a

main.c  mul.c  mul.o  sub.c  sub.o

//靜態鏈結

[yan@localhost src]$ gcc main.c

main.c:1:17: error: fun.h: no such file or directory

找不到標頭檔案

-i(大寫i):指定標頭檔案路徑

[yan@localhost src]$

gcc -i .  main.c  

/tmp/ccrkzuli.o: in function `main':

main.c:(.text+0x42): undefined reference to `add'

main.c:(.text+0x67): undefined reference to `sub'

main.c:(.text+0x8c): undefined reference to `mul'

collect2: ld returned 1 exit status

未找到鏈結庫

-l:指定鏈結庫的位置

-l(小寫l):指定鏈結庫的名字,去掉lib和.a和.so

[yan@localhost src]$

gcc main.c -i ./ -l ./ -l fun -o afun

//main的位置最好放在前面不然會被認為和庫同級

[yan@localhost src]$ ls

add.c

afun

fun.h  

libfun.a

main.c  

mul.c  sub.c

//靜態鏈結後可直接執行

[yan@localhost src]$ ./afun

a = 15,b = 10

a + b = 25

a - b = 5

a * b = 150

動態庫製作示例

//生成動態庫,把main.c先移出去

[yan@localhost src]$ ls

add.c  fun.h mul.c  sub.c

[yan@localhost src]$

gcc -shared -fpic -o libfun.so *.c

[yan@localhost src]$ ls

add.c  fun.h 

libfun.a 

libfun.so

mul.c  sub.c

//當動態和靜態庫同時存在時進行鏈結

[yan@localhost src]$ ls

add.c fun.h 

libfun.a libfun.so 

main.c  mul.c  sub.c

[yan@localhost src]$

gcc main.c -i ./ -l ./ -l fun -o afun

//如要靜態編譯,可以加-static

[yan@localhost src]$ ./afun

./afun: error while loading sh

ared libraries: libfun.so: cannot open shared object file: no such file or directory

//可以看出程式鏈結時優先動態鏈結

//動態鏈結的程式執行時,需要指定動態庫的位置

2種指定動態庫位置的方法:

1.將庫放到/lib或者/usr/lib下(需要root許可權)

2.新增環境變數ld_library_path

[yan@localhost src]$ echo $ld_library_path

//原來的ld_library_path為空,現在新增,比如當前路徑

[yan@localhost src]$

export ld_library_path=`pwd`

[yan@localhost src]$ echo $ld_library_path       

/home/yan/c_work/src

[yan@localhost src]$ ./afun

a = 15,b = 10

a + b = 25

a - b = 5

a * b = 150

file

lddfile檢視檔案型別

[yan@localhost src]$ file afun

afun: elf 64-bit lsb executable, x86-64, version 1 (sysv), dynamically linked (uses shared libs), for gnu/linux 2.6.18, not stripped

ldd檢視檔案所依賴的動態庫

//靜態庫鏈結沒有動態庫所以不顯示

[yan@localhost src]$ ldd afun

linux-vdso.so.1 =>  (0x00007ffcbf2df000)

libfun.so => /home/yan/c_work/src/libfun.so (0x00007fc97d6c2000)

libc.so.6 => /lib64/libc.so.6 (0x0000003929000000)

/lib64/ld-linux-x86-64.so.2 (0x0000003928c00000)

靜態鏈結和動態鏈結

靜態載入dll dll工程b 專案屬性 配置屬性 常規 配置型別 動態庫 dll 在宣告檔案中,宣告匯出函式 declspec dllexport int xx 如果是c檔案,要在c 檔案中被呼叫,註明extern c 可以 ifdef cplusplus extern c endif 呼叫dll的...

靜態鏈結和動態鏈結

1 靜態鏈結庫只包含 lib檔案 動態鏈結庫包含 lib檔案和dll檔案,靜態鏈結庫中不能再包含其他的動態鏈結庫或者靜態庫,而在動態鏈結庫中還可以再包含其他的動態或靜態鏈結庫。此外他們都會用到定義了函式和相關資料結構的.h標頭檔案,其中 h標頭檔案是編譯時必須的,lib是鏈結時需要的,dll是執行時...

靜態鏈結和動態鏈結

動態鏈結庫 靜態庫 import庫區別 windows為應用程式提供了豐富的函式呼叫,這些函式呼叫都包含在動態鏈結庫中。其中有3個最重要的dll,kernel32.dll,它包含用於管理記憶體 程序和執行緒的各個函式 user32.dll,它包含用於執行使用者介面任務 如視窗的建立和訊息的傳送 的各...