1. 使用陷阱宏調用函數時,在遇到異常時不會立即退出到上一層函數,而是將異常退出碼寫入宏內的第一個參數,之後還可以繼續
運行:例如:TRAP(LeaveCode,functionL()),如果函數functionL()由於異常退出而返回,LeaveCode就會被設置成傳遞給
User::Leave()函數調用的值,並繼續運行,如果沒有異常退出,LeaveCode被設置成KErrNone(0),並繼續運行。
這大概就是用陷阱宏調用函數的好處之一吧!
2. 程序例子:
MyFunction()
{
TInt *buff;
buff=new CThisObject;
...
funcL();
delete buff;
}
如果在程序中funcL()發生異常退出,將永不調用delete buff,而buff是一個自動變量,在退出時它將越出作用域,留下只有沒
有任何引用的獨立內存(即所謂的內存泄漏).
可以採取以下例子一樣的方式來解決:
FuncL()
{
CMyObject *myobj=new CMyObject;
CleanupStack::PushL(myobj);
TInt *buff=new TInt(1000);
CleanupStack::PushL(buff);
DoSomethingL();
CleanupStack::Pop(2); //以下幾個語句可以用本語句代替:CleanupStack::PopAndDestroy(2); 彈出並且刪除!
delete *myobj;
delete *buff;
}
在函數運行期間,自動指針變量可被壓到清理棧中。如果函數發生異常退出,壓到清理棧上的每個指針,在該函數退出前全部都
被彈出並被釋放,這樣將防止上一個例子的問題的發生!如果沒有發生異常,就相當與手工彈出! (這種方式在平時的程序中很
常見).
3.以LC結尾的函數提供了一個附加的便利----在成功之後,返回值會被壓入清理棧中所以:
void Func1L()
{
TInt *buff;
buff=User::AllocLC(1000);
...
FooL();
CleanupStack::PopAndDestroy();
}
本例子不用PushL()語句就可以將返回值壓入清理棧中了,不過不要忘了最後還是要加上CleanupStack::PopAndDestroy()語句的!
4.庫:
靜態庫在構建時被鏈接到程序中----提取庫函數,且作爲調用程序的可執行部分,另一方面,DLL時在運行時刻才加載和鏈接。
編寫DLL時,必須遵循以下規則:
* 在.h文件中,對希望提供給DLL用戶使用的每個函數,在前面添加IMPORT_C
* 在.cpp文件中,對希望提供給DLL用戶使用的每個函數,在前面添加EXPORT_C
* 包含入口點函數E32DLL().E32DLL()可以是一個代碼存根,但所有的DLL都需要它。
程序中要使用DLL,可在構建時,通過在mmp文件的LIBRARY 行中增加DLL,來連接DLL導入庫。然後,只要DLL存在於目標程序中,程
序就可以在需要時調用導出的DLL類和函數。
可以通過RLibrary API 手工將DLL加載到內存中,並調用它的DLL函數,這樣可以實現不必連接到DLL導入庫就可以使用DLL,不過
這些函數時通過序數來調用的程序員必須知道函數所對應的序數。
5.命名約定:
以C開頭代表是以CBase基礎的類;
T開頭代表某種數據類型,R開頭代表資源類名前綴,M開頭代表接口類名前綴;
i開頭代表類成員,a開頭代表函數的參數,K開頭代表常數;
枚舉類型以T開頭(因爲枚舉也是一種類型),其中的枚舉成員則以E開頭!
L-----以L結尾的函數,代表可能發生異常退出的函數;
LC——代表可能異常退出,但在異常退出前已經把它們的結果壓入清理棧;
D-----表示該函數負責處理調用該方法所在的對象---即這個函數完成時,它將刪除對象,如下例:
CEikDialog::ExecutedLD(),該函數啓動對話框,一旦用戶取消對話框時,函數銷燬對話框對象本身(注意D前面的L,它表明函數
異常退出)。