关于清理栈的迷惑

hahapro 2009-10-28 10:18:02
刚刚开始学习symbian 遇到了一个让我很费解的问题 请大虾帮忙啊
我弄了一个控制台的程序 程序如下:

#include <e32base.h>
#include <e32std.h>
#include <e32cons.h> // Console
//#include <euser.h>

// Global Variables

GLDEF_D CConsoleBase* console; // write all messages to this

void DoTheThingsForMeL(CConsoleBase* aConsole)
{
aConsole->Write(_L("hello world!"));
// aConsole->Getch();
}
void DoExampleL()
{
// Make the console and push it on the cleanup stack.

CleanupStack::PushL(console);
DoTheThingsForMeL(console);
CleanupStack::PopAndDestroy(console);

}

TInt E32Main()
{
__UHEAP_MARK;
//Create a cleanup stack
CTrapCleanup* cleanup = CTrapCleanup::New();
console = Console::NewL(_L("Console"), TSize( KConsFullScreen, KConsFullScreen));
//Call some Leaving methods inside TRAP
TRAPD(error, DoExampleL());
//Destroy cleanup stack
delete cleanup;
__UHEAP_MARKEND;
return 0;
}

我有一个问题就是为什么 DoExampleL()这个函数必须要写在宏TAAPD里面?单独拿出来就出错,有的人说是因为函数中有CleanupStack::Push()这样的对于清理栈的操作,但是我的理解console = Console::NewL(_L("Console"), TSize( KConsFullScreen, KConsFullScreen)); 这句中应该也包含着这样的操作为什么这样可以?
请高人指点~~
...全文
393 6 打赏 收藏 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
alex_hua 2009-10-28
  • 打赏
  • 举报
回复
你先看一下Console这个类里面有没有定义其他实例化的方法
hahapro 2009-10-28
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 alex_hua 的回复:]
引用楼主 hahapro 的回复:
有的人说是因为函数中有CleanupStack::Push()这样的对于清理栈的操作...


这个理解是对的。任何有CleanupStack::Push()操作的地方,都应被包含着一个TRAP/TRAPD异常捕获宏内。对于你说的console = Console::NewL(_L("Console"), TSize( KConsFullScreen, KConsFullScreen))操作,理论上是应该放到一个TRAP/TRAPD内,因为这个函数是带L的,但从测试结果来看,这个函数不放在里面也可以,那就说明,其实这个带L的方法,里面没有操作清理栈的调用。

你可以在TRAPD(error, DoExampleL()); 调用前,使用一个自己写的L函数验证一下,当这个函数中有CleanupStack::Push()和没有的两种情况,是否是上面那个结论。
[/Quote]

那如果Console::NewL(_L("Console"), TSize( KConsFullScreen, KConsFullScreen))这个函数是没有对于清理栈的操作那个L也就是说明程序可能leave,按照我的理解这个NewL因该是两段构造的标志,应该是使用了清理栈的,两段构造不用清理栈也可以吗?
beyondma 2009-10-28
  • 打赏
  • 举报
回复
DoTheThingsForMeL这个里面没有可能出现异常的函数没有必要叫*L
chenzhp 2009-10-28
  • 打赏
  • 举报
回复
同上
alex_hua 2009-10-28
  • 打赏
  • 举报
回复
[Quote=引用楼主 hahapro 的回复:]
有的人说是因为函数中有CleanupStack::Push()这样的对于清理栈的操作...
[/Quote]

这个理解是对的。任何有CleanupStack::Push()操作的地方,都应被包含着一个TRAP/TRAPD异常捕获宏内。对于你说的console = Console::NewL(_L("Console"), TSize( KConsFullScreen, KConsFullScreen))操作,理论上是应该放到一个TRAP/TRAPD内,因为这个函数是带L的,但从测试结果来看,这个函数不放在里面也可以,那就说明,其实这个带L的方法,里面没有操作清理栈的调用。

你可以在TRAPD(error, DoExampleL()); 调用前,使用一个自己写的L函数验证一下,当这个函数中有CleanupStack::Push()和没有的两种情况,是否是上面那个结论。
hahapro 2009-10-28
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 alex_hua 的回复:]
你先看一下Console这个类里面有没有定义其他实例化的方法
[/Quote]
这个类是这个样子的,看来也就是默认说Console::NewL(_L("Console"), TSize( KConsFullScreen, KConsFullScreen)) 这句里头没有使用清理栈。
class Console
{
public:
IMPORT_C static CConsoleBase* NewL(const TDesC& aTitle,TSize aSize);
};

3,119

社区成员

发帖
与我相关
我的任务
社区描述
塞班系统(Symbian系统)是塞班公司为手机而设计的操作系统,它的前身是英国宝意昂公司的 EP ( Electronic Piece of cheese)操作系统。
社区管理员
  • Symbian社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧