<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                [TOC] ## 動態庫 - 靜態庫的一個缺點是,當同時運行多個應用程序,并且他們都使用來至同一個函數庫的函數時候,內存中就會有同一個函數的多個副本,而且程序文件自身也有多個同樣的副本,占用磁盤和內存的開銷,共享庫就是解決重復庫包含的問題的 - 共享庫保存位置和靜態庫一致,但后綴名是基于.so區分的 - 當一個程序使用共享庫時,它的鏈接方式是:程序不再包含函數代碼,而是應用運行時刻訪問的共享代碼。 - 當編譯好的程序被裝載入內存中執行時候,函數引用被解析并產生對共享庫的函數調用,如果有必要,共享庫才會被加載到內存中(符合按需加載的原則) - 系統可以只保存一份副本供所有有需要的程序共同使用;另外,共享庫函數版本升級時候,僅需要修訂一份文件即可 linux系統負責裝載共享庫并解析執行程序所引用函數的程序是`ld.so`,相關共享庫搜索路徑配置`/etc/ld.so.conf`,修改該配置后,需要通過`ldconfig`來重載配置,可以基于`ldd`命令查看某個程序所依賴的共享庫。 ## 創建動態庫 <details> <summary>myfunc.c</summary> ``` #include "myfunc.h" void say_hello() { printf("hello world\n"); } int cal_sum(int x, int y) { return x + y; } ``` </details> <br/> <details> <summary>myfunc.h</summary> ``` #ifndef __MYFUNC_H #define __MYFUNC_H #include <stdio.h> #include <stdlib.h> void say_hello(); int cal_sum(int x, int y); #endif ``` </details> <br/> 生成動態庫 方式一: ``` gcc -c -fPIC -o myfunc.o myfunc.c -c 表示只編譯 (compile) ,而不鏈接,輸出目標文( obj 文件)。 -o 表示輸出文件的文件名。 -fPIC PIC 指 Position Independent Code , 生成適合在共享庫中使用的與位置無關的代碼。編譯成共享庫要求此選項。適用于動態鏈接并避免對全局偏移表大小的任何限制。 gcc -shared myfunc.o -o libmyfunc.so -share 生成一個共享對象,可以與其他對象鏈接以形成可執行文件。 ``` 方式二:直接分成動態庫 ``` gcc -fPIC -shared myfunc.c -o libmyfunc.so ``` **其實動態鏈接庫有其命名規則**。 ``` 如 libname.so.x.y.z lib :統一前綴; name :動態鏈接庫的名字, libmyfunc.so 中 myfunc 就是其動態鏈接庫名; so :統一后綴; x :主版本號,表示該庫有重大更新,不同版本號之間是不兼容的; y :次版本號,表示該庫增量升級,在相同主版本號下,次版本號高的兼容次版本號低的庫; z :發布版本號,表示該庫的優化、 bugfix 等,相同主次版本號,不同發布版本號之間完全兼容 ``` ## 使用動態鏈接庫 <details> <summary>test.c</summary> ``` #include "myfunc.h" int main(int argc, char const *argv[]) { int result = 0; say_hello(); result = cal_sum(2, 3); printf("%d\n", result); return 0; } ``` </details> <br/> 生成執行文件 ``` gcc -o test test.c -l myfunc -L . // 或 gcc -o test test.c -lmyfunc -L . -l 選項說明庫文件的名字 -L 選項說明庫文件的路徑。`-L .` ,表示當前路徑 ``` 生成的 可執行文件依然會報錯 因為:**執行程序的時候,系統不知道`libmyfunc.so`的位置,系統無法找到庫文件**。盡管我們用 GCC 編譯的時候,通過`-L`選項提供了`libmyfunc.so`文件的位置。**但是這個信息沒有被寫入到可執行程序里面** 可通過 ldd 查看 ``` ldd test linux-vdso.so.1 => (0x00007fff57fb0000) libmyfunc.so => not found libc.so.6 => /lib64/libc.so.6 (0x00007f1fde4fc000) /lib64/ld-linux-x86-64.so.2 (0x00007f1fde8ca000) ``` ## 找不到 .so 的4種方式 ### 放到 GCC 默認搜索目錄 **將`libmyfunc.so`放到 GCC 默認搜索目錄。** 比如`/usr/lib/x86_64-linux-gnu`或者`/lib/x86_64-linux-gnu`,或者 `/usr/lib64`都可以,這樣做簡單粗暴。但是這樣做需要 root 權限來完成。 ### 使用 /etc/ld.so.conf.d **在`/etc/ld.so.conf.d`目錄下新建一個`.conf`文件。** 比如`mylib.conf`,在里面添加第三方庫目錄的絕對路徑(比如`libmyfunc.so`所在目錄的絕對路徑) ### 設置 LD_LIBRARY_PATH 環境變量 比如`export LD_LIBRARY_PATH=.`(`.`代表當前目錄)。當設置這個環境變量后,操作系統將在`LD_LIBRARY_PATH`下搜索庫文件,再到默認路徑中搜索文件 如果需要永久添加變量,需要將`export LD_LIBRARY_PATH=/xxx/xxx:$LD_LIBRARY_PATH`寫入到`~/.bashrc`里面,其中`/xxx/xxx`是庫文件所在目錄的絕對路徑 ### 編譯的時候添加 -Wl,-rpath 選項 ``` gcc -o test test.c -l myfunc -L . -Wl,-rpath=. -Wl 選項告訴編譯器將后面的參數傳遞給鏈接器 ``` 添加此參數后, 可執行文件便會在當前路徑下查看 lib庫
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看