Linux下的動態共享庫 so 開發呼叫

2021-06-16 20:51:10 字數 4643 閱讀 7531

翻譯並根據實際情況進行了小小修改,僅關注linux下動態共享庫(dynamic shared library .so)的開發.

inttest1()

inttest2()

#include 

<

stdio.h

>

inttest1();

inttest2();

intmain()

在**的目錄下執行如下命令: (如果你不是ubuntu系統,請將命令的sudo都去掉)

gcc -wall -fpic -c *.c

gcc -shared -wl

,-soname

,libctest.so

.1-o libctest.so

.1.0

*.osudo mv libctest.so

.1.0

/usr/lib

sudo ln -sf /usr/lib/libctest.so

.1.0

/usr/lib/libctest.so

sudo ln -sf /usr/lib/libctest.so

.1.0

/usr/lib/libctest.so.1

引數詳解:

兩個符號鏈結的含義:

為了使應用程式能夠在執行時載入動態庫,可以通過3種方式指定動態庫的路徑(以下例子均假定/opt/lib是動態庫所在位置):

執行 sudo ldconfig -n /opt/lib

/opt/lib 是動態庫所在路徑.  這種方式簡單快捷,便於程式設計師開發.缺點是重啟後即失效.

開啟/etc/ld.so.confg 檔案,並將/opt/lib 新增進去.

(注: 在ubuntu系統中, 所有so.conf檔案都在/etc/ld.so.conf.d目錄. 你可以仿照該目錄下的.conf檔案寫乙個libctest.conf並將/opt/lib填入)

環境變數的名字一般是ld_library_path, 但是不同的系統可能有不同名字. 例如

linux/solaris:

ld_library_path, sgi:

ld_libraryn32_path, aix:

libpath, mac os x:

dyld_library_path, hp-ux:

shlib_path) (

注: 此說法未經驗證

)修改~/.bashrc , 增加以下指令碼:

if [

-d /opt/lib ];

then

ld_library_path

=/opt/lib:$ld_library_path

fiexport ld_library_path

在第一章的簡單例子中, /usr/lib 是ubuntu預設的動態庫目錄,所以我們不須指定動態庫目錄也能執行應用程式.

保留第一章的test1.c和test2.c檔案,並增加ctest.h標頭檔案如下:

#ifndef ctest_h

#define

ctest_h

#ifdef __cplusplus

extern"c

"#endif

#endif

我們繼續使用第一章生成的libctest.so,僅需增加乙個新的應用程式 prog.c:

#include 

<

stdio.h

>

#include 

<

dlfcn.h

>

#include 

"ctest.h

"int

main(

intargc, 

char

**argv) 

fn =

dlsym(lib_handle, 

"test1");

if((error 

=dlerror()) 

!=null)  

inty

=fn();

printf(

"y=%d\n

",y);

dlclose(lib_handle);

return0;

} 然後用如下命令執行(由於沒有使用其他庫,所以忽略-l等引數):

gcc -wall prog.c -lctest -o prog

-ldl./

progdl

dlopen(

"libctest.so

", rtld_lazy): 載入動態庫,如果載入失敗返回null. 第二個引數可以是:

dlsym(lib_handle, 

"test1

"): 返回函式位址. 如果查詢函式失敗則返回null.

和微軟的動態載入dll技術對比如下:

增加乙個prog2.cpp

#include 

<

dlfcn.h

>

#include 

<

iostream

>

#include 

"ctest.h

"using

namespace

std;

intmain()

//reset errors

dlerror();

//load the symbols (handle to function "test")

//create = (myclass* (*)())dlsym(handle, "create_object");

//destroy = (void (*)(myclass*))dlsym(handle, "destroy_object");

func_handle =(

int(

*)())dlsym(lib_handle, 

"test1");

const

char

*dlsym_error 

=dlerror();

if(dlsym_error) 

cout

<<

"result:= 

"<<

func_handle()

<<

endl;

dlclose(lib_handle);

return0;

} 然後用如下命令執行:

g++ -wall prog2.cpp -lctest -o prog2

-ldl./

prog2

假設c檔案是prog.c, c++呼叫檔案是prog2.cpp,那麼編譯指令碼分別是:

c語言:

gcc -wall -i/path/to/include-files -l/path/to/libraries prog.c -lctest -o prog

c++語言:

g++ -wall -i/path/to/include-files -l/path/to/libraries prog2.cpp -lctest -ldl -o prog2

引數詳解: 命令

可以檢視應用程式所依賴的動態庫,執行如下命令:

ldd prog

在我的機器輸出:

linux-gate.so.1=

>  (0xb80d4000)

libctest.so.1=

> /usr/lib/libctest.so

.1(0xb80be000)

libc.so.6=

> /lib/tls/i686/cmov/libc.so

.6(0xb7f5b000)

/lib/ld-linux.so

.2(0xb80d5000)

#ifndef __myclass_h__

#define

__myclass_h__

class

myclass

;#endif

#include 

"myclass.h

"#include 

<

iostream

>

using

namespace

std;

extern"c

"myclass

*create_object()

extern"c

"void

destroy_object( myclass

*object

)myclass::myclass()

void

myclass::dosomething()

//class_user.cpp

#include 

<

dlfcn.h

>

#include 

<

iostream

>

#include 

"myclass.h

"using

namespace

std;

intmain(

intargc, 

char

**argv)

編譯和執行:

g++ -fpic -shared myclass.cpp -o myclass.so

g++ class_user.cpp -ldl -o class_user

./class_user

Linux下動態庫 so 和靜態庫 a

一般情況下,在專案裡會把功能相似的 封裝成庫,方便使用和管理,同時增加了 的內聚性。庫分為兩種,一種為靜態庫,檔名以.a結尾,另一種是動態庫,檔名以.so結尾。靜態庫和動態庫的使用各有利弊。靜態庫的特點 動態庫的特點 現在用乙個微型的工程,來講述靜態庫 動態庫的生成和使用。假設有3個.c檔案,分別為...

linux下構建 共享函式庫( so)

在linux上用c建立共享庫so 1 建立math1.c,在命令列中輸入 nano math1.c int add int x,int y 2 編譯生成共享庫libmath1.so gcc fpic shared olibmath1.so math1.c 3 建立測試程式testmath.c,在命令...

linux下動態庫( so 的路徑問題

最近在使用wxwidgets,這是乙個跨平台的c 庫,在linux下編譯成動態庫 so 如果將編譯後的可執行檔案發布到其他機器的linux系統中,需要帶上.so檔案,這就需要設定一下這些動態庫的路徑,一般可以使用環境變數ld library path來設定,可以在終端中直接輸出如下的命令 expor...