好幾天

想著想著,

所謂的未來,
順應天命,
或許有那麼一天,
我會後悔,
但我求現在無愧己心,
該放手,
絕不退縮。

如果有永遠的事

永遠

這兩個字,
如此的遙不可及,
那如何做出承諾呢?
如果只是隨口說說,
那又有什麼意義?
人呀,
總不能活在騙自己的謊言中,
期望別人會遵守承諾,
感覺沒有太大意義.

用gcc 自製 Library

Library可分成三種,static、shared與dynamically loaded。

1. Static libraries

Static 程式庫用於靜態連結,簡單講是把一堆object檔用ar(archiver)
包裝集合起來,檔名以 `.a’ 結尾。優點是執行效能通常會比後兩者快,
而且因為是靜態連結,所以不易發生執行時找不到library或版本錯置而
無法執行的問題。缺點則是檔案較大,維護度較低;例如library如果發
現bug需要更新,那麼就必須重新連結執行檔。

1.1 編譯

編譯方式很簡單,先例用 `-c’ 編出 object 檔,再用 ar 包起來即可。

____ hello.c ____
#include
void hello(){ printf(“Hello “); }

____ world.c ____
#include
void world(){ printf(“world.”); }

____ mylib.h ____
void hello();
void world();

$ gcc -c hello.c world.c /* 編出 hello.o 與 world.o */
$ ar rcs libmylib.a hello.o world.o /* 包成 limylib.a */

這樣就可以建出一個檔名為 libmylib.a 的檔。輸出的檔名其實沒有硬性規定,
但如果想要配合 gcc 的 ‘-l’ 參數來連結,一定要以 `lib’ 開頭,中間是你要
的library名稱,然後緊接著 `.a’ 結尾。

1.2 使用

____ main.c ____
#include “mylib.h”
int main() {
hello();
world();
}

使用上就像與一般的 object 檔連結沒有差別。

$ gcc main.c libmylib.a

也可以配合 gcc 的 `-l’ 參數使用

$ gcc main.c -L. -lmylib

`-Ldir’ 參數用來指定要搜尋程式庫的目錄,`.’ 表示搜尋現在所在的目錄。
通常預設會搜 /usr/lib 或 /lib 等目錄。
`-llibrary’ 參數用來指定要連結的程式庫 ,’mylib’ 表示要與mylib進行連結
,他會搜尋library名稱前加`lib’後接`.a’的檔案來連結。

$ ./a.out
Hello world.

2. Shared libraries

Shared library 會在程式執行起始時才被自動載入。因為程式庫與執行檔
是分離的,所以維護彈性較好。有兩點要注意,shared library是在程式起始
時就要被載入,而不是執行中用到才載入,而且在連結階段需要有該程式庫
才能進行連結。

首先有一些名詞要弄懂,soname、real name與linker name。

soname 用來表示是一個特定 library 的名稱,像是 libmylib.so.1 。
前面以 `lib’ 開頭,接著是該 library 的名稱,然後是 `.so’ ,接著
是版號,用來表名他的介面;如果介面改變時,就會增加版號來維護相容度。

real name 是實際放有library程式的檔案名稱,後面會再加上 minor 版號與
release 版號,像是 libmylib.so.1.0.0 。

一般來說,版號的改變規則是(印象中在 APress-Difinitive Guide to GCC中有
提到,但目前手邊沒這本書),最尾碼的release版號用於程式內容的修正,
介面完全沒有改變。中間的minor用於有新增加介面,但相舊介面沒改變,所以
與舊版本相容。最前面的version版號用於原介面有移除或改變,與舊版不相容
時。

linker name是用於連結時的名稱,是不含版號的 soname ,如: libmylib.so。
通常 linker name與 real name是用 ln 指到對應的 real name ,用來提供
彈性與維護性。

2.1 編譯
shared library的製作過程較複雜。

$ gcc -c -fPIC hello.c world.c

編譯時要加上 -fPIC 用來產生 position-independent code。也可以用 -fpic
參數。 (不太清楚差異,只知道 -fPIC 較通用於不同平台,但產生的code較大
,而且編譯速度較慢)。

$ gcc -shared -Wl,-soname,libmylib.so.1 -o libmylib.so.1.0.0
hello.o world.o

-shared 表示要編譯成 shared library
-Wl 用於參遞參數給linker,因此-soname與libmylib.so.1會被傳給linker處理。
-soname用來指名 soname 為 limylib.so.1
library會被輸出成libmylib.so.1.0.0 (也就是real name)

若不指定 soname 的話,在編譯結連後的執行檔會以連時的library檔名為
soname,並載入他。否則是載入soname指定的library檔案。

可以利用 objdump 來看 library 的 soname。

$ objdump -p libmylib.so | grep SONAME
SONAME libmylib.so.1

若不指名-soname參數的話,則library不會有這個欄位資料。

在編譯後再用 ln 來建立 soname 與 linker name 兩個檔案。
$ ln -s libmylib.so.1.0.0 libmylib.so
$ ln -s libmylib.so.1.0.0 libmylib.so.1

2.2 使用

與使用 static library 同。

$ gcc main.c libmylib.so

以上直接指定與 libmylib.so 連結。

或用

$ gcc main.c -L. -lmylib

linker會搜尋 libmylib.so 來進行連結。

如果目錄下同時有static與shared library的話,會以shared為主。
使用 -static 參數可以避免使用shared連結。

$ gcc main.c -static -L. -lmylib

此時可以用 ldd 看編譯出的執行檔與shared程式庫的相依性
$ldd a.out
linux-gate.so.1 => (0xffffe000)
libmylib.so.1 => not found
libc.so.6 => /lib/libc.so.6 (0xb7dd6000)
/lib/ld-linux.so.2 (0xb7f07000)
輸出結果顯示出該執行檔需要 libmylib.so.1 這個shared library。
會顯示 not found 因為沒指定該library所在的目錄,所找不到該library。

因為編譯時有指定-soname參數為 libmylib.so.1 的關係,所以該執行檔會
載入libmylib.so.1。否則以libmylib.so連結,執行檔則會變成要求載入
libmylib.so

$ ./a.out
./a.out: error while loading shared libraries: libmylib.so.1:
cannot open shared object file: No such file or directory

因為找不到 libmylib.so.1 所以無法執行程式。
有幾個方式可以處理。

a. 把 libmylib.so.1 安裝到系統的library目錄,如/usr/lib下
b. 設定 /etc/ld.so.conf ,加入一個新的library搜尋目錄,並執行ldconfig
更新快取
c. 設定 LD_LIBRARY_PATH 環境變數來搜尋library
這個例子是加入目前的目錄來搜尋要載作的library
$ LD_LIBRARY_PATH=. ./a.out
Hello world.

3. Dynamically loaded libraries

Dynamicaaly loaded libraries 才是像 windows 所用的 DLL ,在使用到
時才載入,編譯連結時不需要相關的library。動態載入庫常被用於像plug-ins
的應用。

3.1 使用方式
動態載入是透過一套 dl function來處理。
#include void *dlopen(const char *filename, int flag);
開啟載入 filename 指定的 library。
void *dlsym(void *handle, const char *symbol);
取得 symbol 指定的symbol name在library被載入的記憶體位址。
int dlclose(void *handle);
關閉dlopen開啟的handle。
char *dlerror(void);
傳回最近所發生的錯誤訊息。

____ dltest.c ____
#include
#include
#include int main() {
void *handle;
void (*f)();
char *error;

/* 開啟之前所撰寫的 libmylib.so 程式庫 */
handle = dlopen(“./libmylib.so”, RTLD_LAZY);
if( !handle ) {
fputs( dlerror(), stderr);
exit(1);
}

/* 取得 hello function 的 address */
f = dlsym(handle, “hello”);
if(( error=dlerror())!=NULL) {
fputs(error, stderr);
exit(1);
}
/* 呼叫該 function */
f();
dlclose(handle);
}

編譯時要加上 -ldl 參數來與 dl library 連結
$ gcc dltest.c -ldl
結果會印出 Hello 字串
$ ./a.out
Hello

關於dl的詳細內容請參閱 man dlopen


參考資料:

Creating a shared and static library with the gnu compiler [gcc]
http://www.adp-gmbh.ch/cpp/gcc/create_lib.html

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

APress – Definitive Guide to GCC

BKDRHash

// BKDR Hash Function
unsigned int BKDRHash(char *str)
{
unsigned int seed = 131; // 31 131 1313 13131 131313 etc..
unsigned int hash = 0;

while (*str)
{
hash = hash * seed + (*str++);
}

return (hash & 0x7FFFFFFF);
}

里斯特資訊媒體股份有限公司

里斯特資訊媒體股份有限公司

公司簡介

里斯特資訊媒體(Richi)成立於2007年7月,以數位內容加值服務為核心,不斷嘗試創新網路服務模式,期望在個人化的網路時代裡,為產業尋找新形態的服務架構,為消費者提供更符合個人化需求的服務支援。

成立3年,Richi屢獲國內外創新商業模式獎項。2010年在號稱「矽谷創投聖經」、足以影響全球科技業趨勢的雜誌「紅鯡魚」(Red Herring)年度新創公司評選中,以「虛擬貨幣交換中心」機制的概念,擊敗上百家公司,與台灣興櫃股王PChome商店街並列「2010亞州科技 100強」;並在2011年1月底在美國洛杉磯獲頒「2010 全球科技100強」,是台灣唯一獲得此殊榮的公司,也是台灣暌違已久,再度拿下這個全球新創團隊聖盃的唯一團隊。國內知名雜誌「商業週刊」專訪Richi 創業團隊,將Richi喻為未來的網路央行,並認為Richi是目前台灣最具發展潛力的新創網路公司之一。

看準社群行銷、行動裝置、小額付費與個人化內容等趨勢將帶來的龐大商機,Richi 未來將持續專注於發展社群貨幣(Social Payments)機制,並在台灣網路產業起飛的歷史中,成為所有網路創新團隊與創作者的最佳技術支援後盾。

你也想要在這個產業轉型的歷史性時刻中,占有一席之地嗎?Richi正在尋找一起實現夢想的夥伴。

透過嚴謹的軟體專案管理流程訓練,Richi團隊裡的各個不同部門,不管是業務、行銷、設計或是研發,所有成員都能共同參與創新網路服務的發想、討論與實現,與不同專業的夥伴分工合作,共同實現網路世界裡無限可能的創意。

Richi認為,在網路的時代裡,「人」才是最重要的價值。如果你對於網路的未來充滿無限想像,如果你也認為堅持和努力是實現夢想的最重要特質,我們非常期待你的加入。

主要商品及服務

– 線上虛擬點數交換平台金流機制
– 社群貨幣(Social Payments)與贊助機制
– 內容社群。包含數位時代OpenCrunch、財訊Wealth、河岸留言Open Jam
– 協辦Tech Orange新媒體。以台灣的TechCrunch為目標,創立三周即進入台灣前千大網站。
– 數位內容與數位廣告服務
– Skype VOIP加值服務
– 移動設備之通訊軟體與加值服務

經營理念

Richi在更開放與自由的資訊環境中,以數位內容加值服務為核心,不斷嘗試創新網路服務模式,期望在個人化的網路時代裡,為產業尋找新形態的服務架構,為消費者提供更符合個人化需求的服務支援。並以台灣為出發點,將服務輻射式推廣至不同語系的國家與地區。

php curl multi interface

// create the multi curl handle

$mh = curl_multi_init();

$handles = array();

for($i=0;$i<5;$i++)

{

// create a new single curl handle

$ch = curl_init();

// setting several options like url, timeout, returntransfer

// simulate multithreading by calling the wait.php script and sleeping for $rand seconds

curl_setopt($ch, CURLOPT_URL, "http://put your url here/wait.php?seconds=".($i+1));

curl_setopt($ch, CURLOPT_HEADER, 0);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

curl_setopt($ch, CURLOPT_TIMEOUT, 30);

// add this handle to the multi handle

curl_multi_add_handle($mh,$ch);

// put the handles in an array to loop this later on

$handles[] = $ch;

}

// execute the multi handle

$running=null;

do

{

curl_multi_exec($mh,$running);

// added a usleep for 0.25 seconds to reduce load

usleep (250000);

} while (
$running > 0);

// get the content of the urls (if there is any)

for($i=0;$i<count($handles);$i++)

{

// get the content of the handle

$output.= curl_multi_getcontent($handles[$i]);

// remove the handle from the multi handle

curl_multi_remove_handle($mh,$handles[$i]);

}

// echo the output to the screen

echo $output;

// close the multi curl handle to free system resources

curl_multi_close($mh);

?>