翻譯並根據實際情況進行了小小修改,僅關注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...