我們在編寫Linux運行庫時,特別是作為組件提交給其他程序員使用時,很有必要提供返回消息以提高組件在開發過程中的可用性。本文將為您講述一些實用的技巧。
在編寫C/C++應用時,我們非常熟悉系統調用中的返回消息的處理。在返回消息中,包含了兩類信息,一個是返回信息代碼,指明返回的是何類信息;另一個返回的是信息的文字說明,指明調用是否成功。這兩類信息均有各自的作用,不能相互代替。比如調用加載內存的系統調用,如果該內存已經加載,該調用可能返回錯誤,但是程序可能還會繼續正確運行,如果需要中止程序,則需要了解程序中止的具體原因,這時僅靠返回消息標識是不夠的,返回信息文字說明則立刻讓用戶知道錯誤原因。我們在編寫Linux運行庫時,特別是作為組件提交給其他程序員使用時,很有必要提供類似的返回消息,以提高組件在開發過程中的可用性。
1. 利用標准C庫中的返回消息
在自己組件中的方法或過程中,如果消息比較一般,可以直接利用標准C庫中的返回消息。標准C庫中的返回消息代碼定義列在頭文件errno.h中,返回消息是用從0開始的一個整數值表示的,其中0為正確的返回值,其他為警告類型或錯誤類型的返回值。在標准C庫中,用了一個全局變量errno來指明當前調用的返回消息值。在組件的方法或過程中,可以直接設置errno的值,當然要符合errno.h中的類型定義。在調用組件中的方法或過程時,可以直接調用C中的函數perror()或strerrno()來提交返回消息的文字說明。
2. 實現自定義的返回消息
一般情況下,標准C中的消息不足以反映自己組件中的方法或過程運行狀態的。這時需要實現自己特有的返回消息。主要步驟如下:
第一,規定返回消息代碼。
組件中方法或過程的運行狀態中有一部分要作為返回值,這些返回值要反映多種復雜的運行狀態,有成功返回值、一般運行消息值、警告值、一般錯誤值、嚴重錯誤值等。返回消息代碼要直接反映這些狀態。另外,返回值中還需要反映該方法或過程位於那個組件中。我們可以用一個整數值的頭兩位標識返回類型,其中成功返回值、一般運行消息值用正數,可以分別標識為0X10000000,0X20000000。警告值、一般錯誤值、嚴重錯誤值用負數值,可以分別標識為0X80000000,0X90000000,0XA0000000。而組件可以用第二個字節標識,如事務安全組件用11標識,則可以用0X000B00000標識。返回消息的具體代碼則可以沿用標准C庫中的表示方法,如正確返回值用0標識,某一嚴重錯誤錯誤用5表示。則對於事務安全組件,這兩種消息可以標識為0X100B0000和0XA00B0005。
第二,表述返回消息的文字說明
表述返回消息的文字說明列在組件裡的一個字符串數組中,各個消息的文字說明在數組中的位置按照消息的具體代碼值決定。
例如事務安全組件中定義如下四個返回消息:0,成功返回值;1,事務定義錯誤;2,事務提交錯誤;3,事務返回錯誤。可以在定義如下字符串數組:
char *ReturnMessage_11[] =
{
"成功返回",
"事務定義錯誤",
"事務提交錯誤",
"事務返回錯誤",
(char *)0
};
};
對應的返回消息代碼分別為:0X100B0000,0X900B0001,0X900B0002,0X900B0003。
第三,注冊組件返回消息
在利用組件開發應用時,首先在組件的構造函數或初始化函數中注冊組件返回消息,這一步是隱藏在組件內部。對於外部應用提供了一個全局的指向組件返回消息字符串數組的指針msg_ptr。注冊代碼如下:
void *handle;
char *messageShow;
// 加載該組件的動態庫
handle = dlopen(NULL, RTLD_LAZY);
// 獲得組件的標識
sprintf(messageShow,"ReturnMessage_%d", ComponentIdx);
// 取得組件返回消息字符串數組指針
msg_ptr[ComponentIdx] = dlsym(handle, messageShow);
第四,獲取組件返回消息的文字說明
在注冊組件返回消息後,在應用調用組件中的方法或過程時,一般情況下,可以直接從返回代碼中判斷返回的消息內容。也可以調用組件中的StrError(int rts)方法獲取組件返回消息的文字說明。
該方法的代碼如下:
int ErrnoIdx;
int CompomentIdx;
// 獲得返回消息的具體代碼
ErrnoIdx = rts & 0xFFFF;
// 獲得組件的標識
CompomentIdx = (rts & 00FF0000) >> 16 ;
// 返回組件返回消息的文字說明
return msg_ptr[CompomentIdx][ErrnoIdx] ;
利用如上的技巧,可以使得我們發布的Linux包在使用時具有較好的可用性。