1. 程式人生 > >關於程式執行時載入動態庫失敗的解決方法

關於程式執行時載入動態庫失敗的解決方法

一般我們在Linux下執行某些外部程式的時候可能會提示找不到共享庫的錯誤, 比如:

error while loading shared libraries: libevent-1.4.so.2: cannot open shared object file: No such file or directory

原因一般有兩個, 一個是作業系統裡確實沒有包含該共享庫(lib*.so.*檔案)或者共享庫版本不對, 遇到這種情況那就去網上下載並安裝上即可.

另外一個原因就是已經安裝了該共享庫, 但執行需要呼叫該共享庫的程式的時候, 程式按照預設共享庫路徑找不到該共享庫檔案.

所以安裝共享庫後要注意共享庫路徑設定問題, 如下:

1) 如果共享庫檔案安裝到了/lib或/usr/lib目錄下, 那麼需執行一下ldconfig命令

ldconfig命令的用途, 主要是在預設搜尋目錄(/lib和/usr/lib)以及動態庫配置檔案/etc/ld.so.conf內所列的目錄下, 搜尋出可共享的動態連結庫(格式如lib*.so*), 進而創建出動態裝入程式(ld.so)所需的連線和快取檔案. 快取檔案預設為/etc/ld.so.cache, 此檔案儲存已排好序的動態連結庫名字列表.

2) 如果共享庫檔案安裝到了/usr/local/lib(很多開源的共享庫都會安裝到該目錄下)或其它"非/lib或/usr/lib"目錄下, 那麼在執行ldconfig命令前, 還要把新共享庫目錄加入到共享庫配置檔案/etc/ld.so.conf中, 如下:

# cat /etc/ld.so.conf
include ld.so.conf.d/*.conf
# echo "/usr/local/lib" >> /etc/ld.so.conf
# ldconfig

3) 如果共享庫檔案安裝到了其它"非/lib或/usr/lib" 目錄下,  但是又不想在/etc/ld.so.conf中加路徑(或者是沒有許可權加路徑). 那可以export一個全域性變數LD_LIBRARY_PATH, 然後執行程式的時候就會去這個目錄中找共享庫.

LD_LIBRARY_PATH的意思是告訴loader在哪些目錄中可以找到共享庫. 可以設定多個搜尋目錄, 這些目錄之間用冒號分隔開. 比如安裝了一個

MySQL到/usr/local/mysql目錄下, 其中有一大堆庫檔案在/usr/local/mysql/lib下面, 則可以在.bashrc或.bash_profile或shell里加入以下語句即可:

export LD_LIBRARY_PATH=/usr/local/mysql/lib:$LD_LIBRARY_PATH   

一般來講這只是一種臨時的解決方案, 在沒有許可權或臨時需要的時候使用.


如果程式需要的庫檔案比系統目前存在的庫檔案版本低,可以做一個連結。比如:

error while loading shared libraries: libncurses.so.4: cannot open shared 
object file: No such file or directory 

ls /usr/lib/libncu* 
/usr/lib/libncurses.a   /usr/lib/libncurses.so.5 
/usr/lib/libncurses.so  /usr/lib/libncurses.so.5.3 

可見雖然沒有libncurses.so.4,但有libncurses.so.5,是可以向下相容的 
建一個連結就好了 
ln -s  /usr/lib/libncurses.so.5.3  /usr/lib/libncurses.so.4


------------------

一.一般安裝動態庫方式

     #./configure

     #make

    #make install    

    這樣,動態庫一般安裝在/lib、/usr/lib、/usr/local/lib、自定義目錄下。

二.找不到共享庫檔案的原因

  1.壓根就沒有此共享庫,也就是說系統中根本就沒有此庫或者說沒裝,這時,從網上下載一些詞庫裝上去即可;

    2.已經安裝了該共享庫, 但執行需要呼叫該共享庫的程式的時候, 程式按照預設的路徑找不到共享庫,這也是眾多人面對的情形,下面主要針對此原因進行說明。

三.linux尋找動態連結庫的順序

    1.編譯程式碼時指定的動態庫搜尋路徑,這裡說明一下,不是Makefile中的-L等指定的目錄;

    2.環境變數LD_LIBRARY_PATH指定的動態庫搜尋路徑;

    3.配置檔案/etc/ld.so.conf指定的動態庫搜尋路徑;

    4.系統預設搜尋路徑/lib;

    5.系統預設搜尋路徑/usr/lib.

四.基於順序的解決方法

1.編譯時指定目錄:

     在程式檔案中的.dynamic段包含了一個叫DT_RPATH的項,是一個以冒號分隔的庫檔案搜尋目錄列表,用以搜尋動態庫。

     在編譯程式時,加入 ”-WI,-rpath =目錄“選項,即將動態庫檔案搜尋路徑加入到可執行的連線檔案中,如一個程式main需要使用libaa.so庫,

      則編譯如下,gcc -o main -L. -laa -WI,rpath=./ main.c ,即在執行main程式時,main會先在當前目錄./下查詢所需要的動態庫檔案。

2.LD_LIBRARY_PATH指定目錄:

     LD_LIBRARY_PATH為環境變數,可以export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:動態庫目錄,可以在執行程式時的終端上鍵入,

     此時,其只對當前的登入有效,即關閉此終端後失效;在~/.bashrc或.bash_profile中新增一行後並source ~/.bashrc,這樣可以永久使用。

3.加入/etc/ld.so.conf檔案:

    一般此檔案的內容為:include /etc/ld.so.conf.d/*.conf

在其下面新增一行動態庫的搜尋目錄,然後在終端輸入ldconfig命令即可。

ldconfig是個什麼東東?它是一個linux程式,通常在/sbin下,是root許可權的,簡單的說,它的作用是將/etc/ld.so.conf列出的路徑下的庫檔案

快取到/etc/ld.so.cache中以供使用,因此在改動庫檔案後一定要執行ldconfig.

4和5.將庫檔案放在這兩個系統預設搜尋路徑下即可。

五.明明安裝了高版本,但是還是嫌庫版本低

       如經常在論壇上看到有人問"為什麼我已經安裝了glib-2.4.x,但是編譯gtk -2.4.x 還是提示glib版本太低阿?

這就涉及到PKG_CONFIG_PATH環境變數。

一般在編譯安裝庫時,會出現類似如下情形(編譯gtk -2.4.13):

checking forpkg-config... /usr/bin/pkg-config
checking for glib-2.0 >= 2.4.0 atk >= 1.0.1 pango >= 1.4.0... Package glib-2.0 was not found in the pkg-config
search path.Perhaps you should add the directory containing `glib-2.0.pc'to thePKG_CONFIG_PATH environment variable
No package 'glib-2.0' found
configure: error: Library requirements (glib-2.0 >= 2.4.0 atk >= 1.0.1 pango >= 1.4.0) not met; consider adjusting
the PKG_CONFIG_PATH environment variable if your libraries are in a nonstandard prefix so pkg-config can findthem.

那這三個紅色表明的是幹什麼用的呢?

pkg-config用來向configure程式提供系統軟體資訊,如軟體的版本、庫的版本、路徑等,這些資訊都放在*.pc下。

如庫裝在了/usr/local下,則對應的.pc檔案一般在/usr/local/lib/pkgconfig下,要將此目錄新增到PKG_CONFIG_PATH中

也就是說,在執行./configure時,pkg-config會查詢PKG_CONFIG_PATH指定目錄下的.pc檔案來提供系統軟體的資訊。


相關推薦

關於程式執行載入動態失敗解決方法

一般我們在Linux下執行某些外部程式的時候可能會提示找不到共享庫的錯誤, 比如: error while loading shared libraries: libevent-1.4.so.2: cannot open shared object file: No such file or direc

LoadLibrary載入動態失敗解決辦法

方式一 採用LoadLibraryEx 若DLL不在呼叫方的同一目錄下,可以用LoadLibrary(L"DLL絕對路徑")載入。但若呼叫的DLL內部又呼叫另外一個DLL,此時呼叫仍會失敗。解決辦法是用LoadLibraryEx: LoadLibraryEx("DLL絕對

Qt 之在執行載入共享

簡述 在 Windows 上,共享庫由 .dll 表示;在 Linux 上,由 .so 表示。一個共享庫中的符號被設計為匯出的,以便客戶端可以從中匯入符號。 要使用共享庫,除了 Qt之建立並使用共享庫 中介紹的方式之外,Qt 還提供了一種機制,可以在執行時載

Linux下執行指定動態

  開發程式的過程中,經常會用到一些動態庫,但是動態庫是無法編譯到程式中的,所以安裝程式時可能就需要將動態庫放到預設的路徑下/usr/lib或者/usr/local/lib/ 下等目錄,否則,在執行程式時,就會有類似“libxxx.so找不到”的提示。   那麼如果沒有許可

載入動態失敗的原因分析

載入動態庫有幾方面的原因。歸納如下: 1) 動態庫路徑錯誤。 2) 動態庫依賴缺失。這個可以利用depends工具看下依賴情況。如果缺失,請尋找相應庫,然後把相應庫放在程式同一目錄下,或者放在system32目錄下。 3) 依賴動態庫本身有問題。這個最難定位。有的時候,依賴

Notepad++開發JavaScript執行中文出現亂碼的解決方法

    如果在Notepad++編輯器開發JS時,在JS檔案中,中文在網頁上可能會顯示為亂碼,遇到這種情況不妨採用本文章中的方法來試一試,或許能解決使你很頭疼的問題。    JS編碼轉換,這句話本身就

如何將程式執行檔案和靜態載入動態放在不同的目錄

一般windows程式的exe和dll需要放在同一個目錄,靜態載入才不會報錯,否則需要修改path環境變數,將所有沒有和exe放在同一目錄的dll的路徑加在path環境變數中。 有沒有一種方法不去手動修改path環境變數並且可以將exe和dll隨心所欲的改變路徑呢?我沒有發

Linux下執行呼叫動態連結.so的三種方法(筆記)

在/etc/ld.so.conf.d/下建立xxx.conf,在文字中加入.so所在路徑,如:/usr/xxx等等,然後使用相應ldconfig命令使之生效。 將.so所在路徑新增為LD_LIBRARY_PATH環境變數。 在編譯命令中使用-Wl,-rpath

解決Revit開發程式執行,按ESC退出報錯問題

對特定的異常進行捕獲和報錯  try { var reference = uidoc.Selection.PickObject(ObjectType.Element, "請選擇您要檢視的元素"); } catch (Autodesk.Revit.Exceptions.Opera

Assembly.LoadFrom載入程式集型別轉換失敗解決方法

為了讓我的wcf模組框架支援自定義通道上下文,對程式碼又進行了一次小型的重構,測試時發現型別轉換的錯誤,最後發現是loadfrom引起的。如果向 loadfrom 上下文中載入了一個程式集,則將啟用 loadfromcontext 託管除錯助手 (mda)。因為預設時載入程式集是在defaul上下文的,所以就

java程式執行過程中動態載入jar包

最近做一個遠端介面測試系統,遇到了動態載入jar包的問題,如將使用者上傳的jar包動態載入後呼叫遠端介面的方法,特將例子記錄下來以便查詢。package cn.baokx.test_addjar; import java.io.File; import java.lang

Android 解決Handler在執行載入報空指標異常

1.可自定義一個這樣的WeakReferenceHandler public class WeakReferenceHandler<T> extends Handler { pr

執行呼叫動態連結 VS2010示例

這裡不再介紹動態連結庫概念等知識,純粹新建一個專案用來表述怎麼在執行時呼叫動態連結庫,程式碼中會給出相關注釋。開發工具用的是VS2010旗艦版。 一、建立動態連結庫專案: 1.新建專案——選擇Win32專案,輸入名稱後(這裡我輸入的專案名稱為sunlib),然後選擇下

機器學習--python程式執行,Qt無法載入windows外掛

複製而不要剪下,這樣就將.all檔案放入了應用程式的目錄下。然後配置環境變數QT_QPA_PLATFORM_PLUGIN_PATH,值為anaconda->pkgs->qt-5.6.2...->library->plugins->platforms。然後重啟pycharm即可。。

動態連結(DLL)初始化例程失敗 解決方法

重灌了系統,在安裝VIVADO的時候報錯:LoadLibrary failed with error 1114: 動態連結庫(DLL)初始化例程失敗,不知道怎麼回事,在知乎上看到一篇帖子:https://zhuanlan.zhihu.com/p/25054452對就是這個錯誤

VS 2013程式點選Ctrl+F5執行出現執行視窗閃退現象的解決方法

用VS2013建立一個C++空專案的時候會出現執行視窗閃退的現象,百度一下找到解決方案 1.首先,右擊解決方案下專案名稱,選擇屬性 2.在連結器--->系統中找到子系統,將子系統選擇成控制檯,     3.然後點選Ctrl+F5,就可以運行了

KVM執行資訊清理命令virt-sysprep -d失敗解決方法

報錯資訊如下,截圖如上; [ 0.0] Examining the guest ... virt-sysprep: error: libguestfs error: could not create appliance through libvirt. Try running

Flex Image 執行載入圖片不顯示

1:圖片路徑寫法是image.source="img/wait.gif" 2:swf放到jsp裡面引用,jsp和swf不在一個目錄下,發現圖裂。 3:如果直接訪問Main.swf是正常的。 4:tomcat目錄是app/flexservice/flexEnter.jsp,app/swf/Mai

沒有載入動態導致的error: symbol lookup error: undefined symbol

做了一個瀏覽器外掛,需要編譯為 abcPlugins.so , 這個.so需要呼叫另外一個業務庫 defLib.so裡面的函式。 把abcPlugins.so替換到目標板上,瀏覽器程序啟動不起來。   1. 查詢瀏覽器程序啟動過程錯誤    1

java程式碼的MapReduce打包成jar 報錯: JAVA程式執行出現:Exception in thread "main" java.lang.ArrayIndexOutOfBoundsEx

以前的學習筆記,整理一下: java程式碼的MapReduce打包成jar 報錯: JAVA程式執行時出現:Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0 at PrintWhat.main(Pri