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,它表明函数
异常退出)。