『壹』 linux下動態鏈接庫的顯式調用是否必須將.so文件放入系統默認的lib目錄
可以放在當前目錄下,但是要設置一下庫文件的路徑:LD_LIBRARY_PATH=./:/usr/local/pet20/lib:/lib/:/usr/local/lib export LD_LIBRARY_PATH 這樣,在調用內的時候就會容自動從當前目錄找。 如果是顯式調用則不用,只要在程序里指定.so的文件路徑就可以了。所以放在當前目錄下也是沒問題的。
希望採納
『貳』 如何在 Linux 下調試動態鏈接庫
大家都知道在 Linux 可以用 gdb 來調試應用程序,當然前提是用 gcc 編譯程序時要加上
-g 參數。
我這篇文章里將討論一下用 gdb 來調試動態鏈接庫的問題。
首先,假設我們准備這樣的一個動態鏈接庫:
QUOTE:
庫名稱是: ggg
動態鏈接庫文件名是: libggg.so
頭文件是: get.h
提供這樣兩個函數調用介面:
int get ();
int set (int a);
要生成這樣一個動態鏈接庫,我們首先編寫這樣一個頭文件:
[Copy to clipboard]
CODE:
/************關於本文檔********************************************
*filename: get.h
*purpose: 一個動態鏈接庫頭文件示例
*tided by: zhoulifa() 周立發 ()
Linux 愛好者 Linux 知識傳播者 SOHO 族 開發者 最擅長 C 語言
*date time: 2006-11-15 21:11:54
*Note: 任何人可以任意復制代碼並運用這些文檔,當然包括你的商業用途
* 但請遵循 GPL
*Hope:希望越來越多的人貢獻自己的力量,為科學技術發展出力
* 科技站在巨人的肩膀上進步更快!感謝有開源前輩的貢獻!
*感謝 提供原始代碼,
我在他的基礎上整理了此文
*********************************************************************/
int get ();
int set (int a);
然後准備這樣一個生成動態鏈接庫的源文件:
[Copy to clipboard]
CODE:
/************關於本文檔********************************************
*filename: get.cpp
*purpose: 一個動態鏈接庫源文件示例
*tided by: zhoulifa() 周立發 ()
Linux 愛好者 Linux 知識傳播者 SOHO 族 開發者 最擅長 C 語言
*date time:2006-11-15 21:11:54
*Note: 任何人可以任意復制代碼並運用這些文檔,當然包括你的商業用途
* 但請遵循 GPL
*Hope:希望越來越多的人貢獻自己的力量,為科學技術發展出力
* 科技站在巨人的肩膀上進步更快!感謝有開源前輩的貢獻!
*感謝 提供原始代碼,
我在他的基礎上整理了此文
*********************************************************************/
#include <stdio.h>
#include "get.h"
static int x=0;
int get ()
{
printf ("get x=%d\n", x);
return x;
}
int set (int a)
{
printf ("set a=%d\n", a);
x = a;
return x;
}
然後我們用 GNU 的 C/C++ 編譯器來生成動態鏈接庫,編譯命令如下:
QUOTE:
g++ get.cpp -shared -g -DDEBUG -o
libggg.so
這樣我們就准備好了動態鏈接庫了,下面我們編寫一個應用程序來調用此動態鏈接庫,源代碼如下:
[Copy to clipboard]
CODE:
/************關於本文檔********************************************
*filename: pk.cpp
*purpose: 一個調用動態鏈接庫的示例
*tided by: zhoulifa() 周立發 ()
Linux 愛好者 Linux 知識傳播者 SOHO 族 開發者 最擅長 C 語言
*date time:2006-11-15 21:11:54
*Note: 任何人可以任意復制代碼並運用這些文檔,當然包括你的商業用途
* 但請遵循 GPL
*Hope:希望越來越多的人貢獻自己的力量,為科學技術發展出力
* 科技站在巨人的肩膀上進步更快!感謝有開源前輩的貢獻!
*感謝 提供原始代碼,
我在他的基礎上整理了此文
*********************************************************************/
#include <stdio.h>
#include "get.h"
int main (int argc, char** argv)
{
int a = 100;
int b = get ();
int c = set (a);
int d = get ();
printf ("a=%d,b=%d,c=%d,d=%d\n",a,b,c,d);
return 0;
}
編譯此程序用下列命令,如果已經把上面生成的 libggg.so 放到了庫文件搜索路徑指定的文件目錄,比如 /lib 或 /usr/lib 之類的,就用下面這條命令:
QUOTE:
g++ pk.cpp -o app -Wall -g -lggg
否則就用下面這條命令:
QUOTE:
g++ pk.cpp -o app -Wall -g -lggg -L`pwd`
下面我們就開始調試上面命令生成的 app 程序吧。如果已經把上面生成的 libggg.so 放到了庫文件搜索路徑指定的文件目錄,比如 /lib或 /usr/lib 之類的,調試就順利完成,如下
:
QUOTE:
./app
GNU gdb 6.4-debian
Copyright 2005 Free Software Foundation,Inc.
GDB is free software, covered by the GNU
General Public License, and you are
welcome to change it and/or distribute
copies of it under certain conditions.
Type "show ing" to see theconditions.
There is absolutely no warranty for GDB.
Type "show warranty" for details.This GDB was configured as "i486-linux-
gnu"...Using host libthread_db library"/lib/tls/i686/cmov/libthread_db.so.1".
(gdb) b main /* 這是在程序的 main 處設置斷點 */
Breakpoint 1 at 0x804853c: file pk.cpp,line 7.
(gdb) b set /* 這是在程序的 set 處設置斷點 */
Function "set" not defined.
Make breakpoint pending on future shared
library load? (y or [n]) y /* 這里必須選擇 y 調試程序才會跟蹤到動態鏈接庫內部去
*/Breakpoint 2 (set) pending.
(gdb) run /* 開始運行我們的程序,直到遇見斷點時暫停 */
Starting program: /data/example/c/app
Breakpoint 3 at 0xb7f665f8: file get.cpp,line 11.
Pending breakpoint "set" resolved
Breakpoint 1, main (argc=1,argv=0xbf990504) at pk.cpp:7
7 int a = 100;
(gdb) n /* 繼續執行程序的下一行代碼
*/
8 int b = get ();
(gdb) n /* 程序執行到了我們斷點所在的動態鏈接庫了 */
get x=0
9 int c = set (a);(gdb) n
Breakpoint 3, set (a=100) at get.cpp:11
11 printf ("set a=%d\n", a);
(gdb) list /* 查看當前代碼行周圍的代碼,證明我們已經跟蹤到動態鏈接庫的源代碼裡面了 */
6 printf ("get x=%d\n", x);
7 return x;
8 }
9 int set (int a)
10 {
11 printf ("set a=%d\n", a);
12 x = a;
13 return x;
14 }
(gdb) n
set a=100
12 x = a;(gdb) n
13 return x;(gdb) n
14 }
(gdb) n
main (argc=1, argv=0xbf990504) at
pk.cpp:10
10 int d = get ();
(gdb) n
get x=100
11 printf ("a=%d,b=%d,c=%
d,d=%d\n",a,b,c,d);
(gdb) n
a=100,b=0,c=100,d=100
12 return 0;
(gdb) c
Continuing.
Program exited normally.
(gdb) quit /* 程序順利執行結束 */#
如果我們沒有把動態鏈接庫放到指定目錄,比如/lib裡面,調試就會失敗,過程如下:
QUOTE:
# gdb ./app
GNU gdb 6.4-debian
Copyright 2005 Free Software Foundation,
Inc.
GDB is free software, covered by the GNU
General Public License, and you arewelcome to change it and/or distribute
copies of it under certain conditions.
Type "show ing" to see theconditions.
There is absolutely no warranty for GDB.
Type "show warranty" for details.
This GDB was configured as "i486-linux-
gnu"...Using host libthread_db library
"/lib/tls/i686/cmov/libthread_db.so.1".
(gdb) b main
Breakpoint 1 at 0x804853c: file pk.cpp,
line 7.
(gdb) b set
Function "set" not defined.
Make breakpoint pending on future shared
library load? (y or [n]) y
Breakpoint 2 (set) pending.
(gdb) run /* 雖然調試操作都一樣,但程序執行失敗 */
Starting program: /data/example/c/app
/data/example/c/app: error while loading
shared libraries: libggg.so: cannot open
shared object file: No such file or
directory
Program exited with code 0177.
(gdb) quit
#
本次實驗的環境是:
CPU:AMD Athlon(tm) 64 Processor 3000+
內存:512M
OS:Ubuntu GNU/Linux 6.06 dapper LTS
gcc:gcc 版本 4.0.3 (Ubuntu 4.0.3-1ubuntu5)
break(b) 行號:在某一行設置斷點
break 函數名:在某個函數開頭設置斷點
break...if...:設置條件斷點
continue(或c):從當前位置開始連續而非單步執行程序
delete breakpoints:刪除所有斷點
delete breakpoints n:刪除序號為n的斷點
disable breakpoints:禁用斷點
enable breakpoints:啟用斷點
info(或i) breakpoints:參看當前設置了哪些斷點
run(或r):從開始連續而非單步執行程序
display 變數名:跟蹤查看一個變數,每次停下來都顯示它的值
undisplay:取消對先前設置的那些變數的跟蹤
『叄』 LLINUX GCC 編譯C使用自定義動態鏈接庫.so的問題
1. 可以參考如下關於庫文件的文章:http://numanal.com/?p=129
2. 在編譯文件時最好用-L指明自定義庫的存在回目錄, 利用如下任一語句答(.so文件與.c文件在同一目錄):
gcc test.c -o test2 -L./verify.so
gcc test.c -o test2 -L.
3. 你這里在的問題應該與編譯器的某些兼容性有關, 在實際編寫程序的時候最好按gcc的語法規范走, 避免不必要的錯誤.
『肆』 基於Debian的linux上如何調用dll動態鏈接庫,或者.so文件
用交叉編譯環境是可以的。
如mingw。
建議在Windows下安裝mingw,然後調試。直接調用是肯定不行的。
參考我的博客:
有個 mono你可以試試,或者是利用wine來讀取,不過不管怎麼樣都不能直接讀取,但是間接的是可以的。大概的就這兩種方法,你可以去wine和mono的網站看看。
應該有不少這方面的資料的
『伍』 關於linux下連接動態庫問題
gcc編譯時,當使用動態庫編譯可以按照幾種寫法
1.gcc test.c ./libSDL2-2.so
2.gcc test.c -lSDL2-2
3.gcc test.c -L/home/test -lSDL2-2
一般的編譯參數都是按照2或3去寫
2寫法的含義是從/lib或者/usr/lib目錄下尋找名稱為SDL2-2的庫,即尋找/lib/libSDL2-2.so或者/usr/lib/libSDL2-2.so文件進行鏈接,當然如果沒有動態庫就會去找靜態庫,再沒有應該就會在編譯時報錯
3寫法的含義是從-L參數首先從指定的目錄中尋找需要鏈接的庫文件,隨後再去尋找系統文件夾中是否存在需要的庫
1寫法的含義是將當前目錄下的./libSDL2-2.so.0文件鏈接進最終文件,因此執行readelf -a a.out後在動態庫部分所看到的路徑就是./libSDL2-2.so.0,進而在執行文件時僅會從當前目錄下尋找libSDL2-2.so.0文件,當執行文件時所在的目錄下沒有該文件時就會出現找不到庫文件的操作
你第二次操作時,因為function.so庫文件與a.out文件在同一個目錄,同時也是在該目錄下執行的ldd操作及運行a.out,a.out在載入動態庫時從當前目錄下找到了所需要的庫文件,此時能夠執行成功(ldd命令實質是一個腳本,通過設置環境變數運行動態庫鏈接器來輸出所有待鏈接的動態庫)。
你可以試試將a.out拷貝至其他目錄再次運行,將出現和第一次操作時一樣的現象,找不到function.so文件。
具體的解決方法就是修改編譯參數,將./libSDL2-2.so.0修改為-lSDL2-2並將libSDL2-2.so.0文件拷貝至/usr/lib目錄下,並且可能因為沒有修改鏈接器的緩存文件(將可能找不到帶版本號後綴的動態庫),需要在/usr/lib目錄下建立一個文件連接(ln -s libSDL2-2.so.0 libSDL2-2.so)或者直接修改名稱為libSDL2-2.so
『陸』 什麼是linux中的SO動態庫
so動態鏈接庫是對它有依賴關系的程序運行時需要調用的,可以通過命令:
ldd 「程序名字」來查看程序調用了哪些動態鏈接庫,系統默認會自動載入/usr/lib/ 等目錄下的動態鏈接庫,如果是源碼安裝的庫,它的動態鏈接庫文件會存在你自定義安裝的目錄的lib下,這時你需要修改/etc/ld.so.conf文件來指定動態鏈接庫的載入路徑,然後運行ldconfig命令來載入動態鏈接庫,ldconfig -v是查看那些動態鏈接庫已經被載入了
『柒』 請問我有一個.so文件,如何在Linux下編程使用呢
-lxx
xx是你的.so文件名
其實使用方法和你使用數學庫函數是一樣的,源代碼中添加
#include <math.h>,編譯的時候,加上-lm參數。
註:linux下的.so文件為共享庫,相當於windows下的dll文件。
linux下編寫調用so文件實例
.so是Linux(Unix)下的動態鏈接庫. 和.dll類似.
比如:
文件有: a.c, b.c, c.c
gcc -c a.c
gcc -c b.c
gcc -c c.c
gcc -shared libXXX.so a.o b.o c.o
要使用的話也很簡單. 比如編譯d.c, 使用到libXXX.so中的函數, libXXX.so地址是MYPATH
gcc d.c -o d -LMYPATH -lXXX
注意不是-llibXXX
test.c文件和一個test.h,這兩個文件要生成libsotest.so文件。然後我還有一個testso.c文件,在這個文件裡面調用libsotest.so中的函數。
編寫的過程中,首先是編譯so文件,我沒有編寫makefile文件,而是參考的2裡面說的直接寫的gcc命令。
因為so文件裡面沒有main函數,所以是不可執行的,所以編譯的時候要加上-c,只生成目標文件。