SIPP 代碼學習筆記1- compress

來源:互聯網
上載者:User

SIPP 尚不支援compress , 但是已經列入計劃,代碼中也留好了調用動態連結程式庫的介面。  

+++++++++++++++++++++++++++++++++++++++

#define COMP_MAIN

#include "comp.h"

#include <dlfcn.h>

#include <string.h>

char * comp_load()

void *handle; 

char *error;  

comp_error[0] = 0;   

handle = dlopen(COMP_PLUGGIN, RTLD_LAZY); 

if (!handle)

{   

strcpy(comp_error, dlerror());   

return comp_error; 

}   

*(void **)(&comp_compress) = dlsym(handle, "comp_compress"); 

 if((error = (char *) dlerror()))   

{

strcpy(comp_error, error);

return comp_error;

}   

*(void **)(&comp_uncompress) = dlsym(handle, "comp_uncompress");  if((error = (char *) dlerror()))   

{

strcpy(comp_error, error);

return comp_error;

}   

*(void **)(&comp_free) = dlsym(handle, "comp_free"); 

if((error = (char *) dlerror()))   

{

strcpy(comp_error, error);

return comp_error;

}   

return 0;

}

+++++++++++++++++++++++++++++++++++++

  下面是對某些知識點的解釋,轉自其他文章, 

相關函數的說明如下: (1)dlopen() 第一個參數:指定共用庫的名稱,將會在下面位置尋找指定的共用庫。 -環境變數LD_LIBRARY_PATH列出的用分號間隔的所有目錄。 -檔案/etc/ld.so.cache中找到的庫的列表,用ldconfig維護。 -目錄usr/lib。 -目錄/lib。 -目前的目錄。 第二個參數:指定如何開啟共用庫。 其中flag有:RTLD_LAZY RTLD_NOW RTLD_GLOBAL,其含義分別為:RTLD_LAZY:在dlopen返回前,對於動態庫中存在的未定義的變數(如外部變數extern,也可以是函數)不執行解析,就是不解析這個變數的地址。RTLD_NOW:與上面不同,他需要在dlopen返回前,解析出每個未定義變數的地址,如果解析不出來,在dlopen會返回NULL,錯誤為:: undefined symbol: xxxx.......RTLD_GLOBAL:它的含義是使得庫中的解析的定義變數在隨後的隨後其它的連結庫中變得可以使用。 (2)dlsym() 調用dlsym時,利用dlopen()返回的共用庫的phandle以及函數名稱作為參數,返回要載入函數的入口地址。 (3)dlerror() 該函數用於檢查調用共用庫的相關函數出現的錯誤。 gcc -fpic -shared -o libstr.so Strlen.c Strnlen.c -fpic 使輸出的對象模組是按照可重定位地址方式產生的。 -shared指定把對應的源檔案產生對應的動態連結程式庫檔案libstr.so檔案。 nm命令

  nm命令可以列出一個函數庫檔案中的符號表。它對於靜態函數庫和共用的函數庫都起作用。對於一個給定的函數庫,nm命令可以列出函數庫中定義的所有符號,包括每個符號的值和類型。還可以給出在原程式中這個函數(符號)是在多少行定義的,不過這必須要求編譯該函數庫的時候加“-l”選項。

  關於符號的類型,這裡我們再多討論一下。符號的類型是以一個字母的形式顯示的,小寫字母表示這個符號是本地(local)的,而大寫字母則表示這個符號是全域的(global,externel)。一般來說,類型有一下幾種:T、D、B、U、W。各自的含義如下:T表示在程式碼片段中定義的一般變數符號;D 表示時初始化過的資料區段;B表示初始化的資料區段;U表示沒有定義的,在這個庫裡面使用了,但是在其他庫中定義的符號;W,weak的縮寫,表示如果其他函數庫中也有對這個符號的定義,則其他符號的定義可以覆蓋這個定義。

  如果你知道一個函數的名字,但是你不知道這個函數在什麼庫中定義的,那麼可以用mn的“-o”選項和grep命令來尋找庫的名字。-o選項使得顯示的每一行都有這個函數庫檔案名稱。例如,你要尋找“cos”這個是在什麼地方定義的,大致可以用下面的命令:

nm -o /lib/* /usr/lib/* /usr/lib/*/* /usr/local/lib/* 2> /dev/null

| grep 'cos$'

  關於nm的更詳細的用法我們可以參考info文檔,位置是info:binutils#nm。

特殊函數_init和_fini

  函數庫裡面有兩個特殊的函數,_init和_fini,這個我們在前面已經說過了。主要是分別用來初始化函數庫和關閉的時候做一些必要的處理,我們可以把自己認為需要的代碼放到這兩個函數裡面,它們分別在函數庫被載入和釋放的時候被執行。具體說,如果一個函數庫裡面有一個名字為“_init”的函數輸出,那麼在第一次通過dlopen()函數開啟這個函數庫,或者只是簡單的作為共用函數庫被開啟的時候,_init函數被自動調用執行。與之相對應的就是 _fini函數,當一個程式調用dlclose()去釋放對這個函數庫的引用的時候,如果該函數庫的被引用計數器為0了,或者這個函數庫是作為一般的共用函數庫被使用而使用它的程式正常退出的時候,_fini就會被調用執行。C語言定義它們的原型如下:

void _init(void); void _fini(void);

  當用gcc編譯來源程式為“.o”檔案的時候,需要加一個“-nostartfiles”選項。這個選項使得C編譯器不連結系統的啟動函數庫裡面的啟動函數。否則,就會得到一個“multiple-definition”的錯誤。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.