程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 淺析C/C++ library

淺析C/C++ library

編輯:C++入門知識

  原來跑的好好的進程,重啟後沒跑多少就掛掉了,奇怪了。經過跟蹤,原來是加載了一個

C/C++ library靜態庫(Static Libraries)、共享庫(shared Libraries)和動態加載庫(ynamically loaded DL libraries)。

靜態庫在程序編譯時會被連接到可執行程序中,程序運行時將不再需要該靜態庫。

共享庫在程序編譯時並不會被連接到可執行程序中,而是在可執行程序啟動時被載入內存的,因此在程序運行時還需要動態庫存在。

動態加載庫在可執行程序執行的任何時候可以被加載。 DL libraries aren't really a different kind of library format (both static and shared libraries can be used as DL libraries。

3 Static Libraries

創建方法:

ar rcs libmy_library.a file1.o file2.o

4 Shared Libraries

4.1 

soname: version number

library

realname: soname

linkername: 以

ldconfig

有如下的指向關系

soname -> realname

linkername -> realname

例子如下所示:

soname ----> /usr/lib/libreadline.so.3 -> /usr/lib/libreadline.so.3.0

realname ----> /usr/lib/libreadline.so.3.0

linkername ----> /usr/lib/libreadline.so -> /usr/lib/libreadline.so.3

所以一般的情況是

linkername -> soname -> realname

4.2 

當執行一個。/etc/ld.so.preload 文件當中指示那些預加載的,優先級高於一般,為了提高加載效率,不用每次執行一個程序都去搜索,便有了文件,每次有新的。

4.3 環境變量

4.3.1 LD_LIBRARY_PATH

LD_LIBRARY_PATH程序加載運行期間查找動態鏈接庫時指定除了系統默認路徑之外的其他路徑,注意,

export LD_LIBRARY_PATH=LIBDIR1:LIBDIR2:$LD_LIBRARY_PATH

4.3.2 LIBRARY_PATH

LIBRARY_PATH程序編譯期間查找動態鏈接庫時指定查找共享庫的路徑,例如,指定

export LIBRARY_PATH=LIBDIR1:LIBDIR2:$LIBRARY_PATH

4.3.3 LD_PRELOAD

這個變量的作用類似於/etc/ld.so.preload

4.3.4 LD_DEBUG=files/libs/bindings/versions/help

通過這個變量的設置會顯示

4.4 

4.4.1 動態鏈接庫管理命令ldconfig

    為了讓動態鏈接庫為系統所共享,還需運行動態鏈接庫的管理命令--ldconfig.

    ldconfig命令的用途,主要是在默認搜尋目錄(/lib和/usr/lib)以及動態庫配置文件/etc/ld.so.conf內所列的目錄下,搜索出可共享的動態鏈接庫(格式如前介紹,lib*.so*),進而創建出動態裝入程序(ld.so)所需的連接和緩存文件.緩存文件默認為/etc/ld.so.cache,此文件保存已排好序的動態鏈接庫名字列表。

ldconfig通常在系統啟動時運行,而當用戶安裝了一個新的動態鏈接庫時,就需要手工運行這個命令。

4.4.2 ldd

ldd:首先,設置某個變量,,然後,執行這個程序。

4.5 

gcc -fPIC -g -c -Wall a.c

gcc -fPIC -g -c -Wall b.c

gcc -shared -Wl,-soname,libmystuff.so.1 \

    -o libmystuff.so.1.0.1 a.o b.o -lc

-fPIC與-fpic比較,fPIC編譯的文件比較大,和平台無關,fpic編譯的比較小,和平台有關。不用使用-fomit-frame-pointer這個編譯參數除非你不得不這樣。雖然使用了這個參數獲得的函數庫仍然可以使用,但是這使得調試程序幾乎 沒有用,無法跟蹤調試。需要使用“-Wl,-export-dynamic”這個選項參數。通常,動態函數庫的符號表裡面包含了這些動態的對象的符號。 這個選項在創建ELF格式的文件時候,會將所有的符號加入到動態符號表中。可以參考ld的幫助獲得更詳細的說明。如果在linux可以用``-rdynamic'' 代替``-Wl,export-dynamic''。

在開發過程中,想修改一個庫,但該庫也用於許多其他程序, 你不希望其他程序使用修改的庫,只讓一個特定的應用程序測試,一個鏈接選項:`rpath'

 -Wl,-rpath,$(DEFAULT_LIB_INSTALL_PATH)

5 Dynamically Loaded (DL) Libraries

使用動態加載庫:

    #include <stdlib.h>

    #include <stdio.h>

    #include <dlfcn.h>

 

    int main(int argc, char **argv) {

        void *handle;

        double (*cosine)(double);

        char *error;

 

        handle = dlopen ("/lib/libm.so.6", RTLD_LAZY);

        if (!handle) {

            fputs (dlerror(), stderr);

            exit(1);

        }

 

        cosine = dlsym(handle, "cos");

        if ((error = dlerror()) != NULL)  {

            fputs(error, stderr);

            exit(1);

        }

 

        printf ("%f\n", (*cosine)(2.0));

        dlclose(handle);

    }

編譯命令為:

    gcc -o foo foo.c -ldl

6 參考

http://tldp.org/HOWTO/Program-Library-HOWTO/

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved