Namespaces

Variants
Actions

Please note that as of October 24, 2014, the Nokia Developer Wiki will no longer be accepting user contributions, including new entries, edits and comments, as we begin transitioning to our new home, in the Windows Phone Development Wiki. We plan to move over the majority of the existing entries over the next few weeks. Thanks for all your past and future contributions.

Использование ловушки(TRAP)

From Wiki
Jump to: navigation, search
Article Metadata

Статья
Перевод:
Оригинал: Using TRAP
Den123
Последнее редактирование: hamishwillee (08 Dec 2011)

Исходный код который может привести к возникновению сброса, должен запускаться в рамках ловушки(TRAP). Если произойдет сброс, управление будет передано последней объявленной ловушке, при этом будет передан код сброса. Следовательно не все "сбрасываемые" функции должны вызываться в рамках TRAP а только те, которые находятся на вершине стека вызовов. Если "сбрасываемая" функция не находится на вершине стека и вызывает другую функция в которой может произойти сброс, TRAP можно не использовать.

Макросы для реализации ловушек

Всего существует три подобных макроса: TRAP, TRAPD, TRAP_IGNORE. Они отличаются только тем, как обходятся с кодом сброса. Для использования макроса TRAP Вы должны предварительно объявить целочисленную переменную в которую будет записан код ошибки:

TInt err;
TRAP(err, LeavingFunctionL());

Макрос TRAPD сам объявляет переменную в которую будет записан код ошибки:

TRAPD(err, LeavingFunctionL());

Макрос TRAP_IGNORE используется в случае если код ошибки не нужен:

TRAP_IGNORE(LeavingFunctionL());

Где должны быть расположены ловушки ?

Ответ на этот вопрос можно найти здесь: Exception handling in Symbian OS.

Советы и приемы использования

Не вызывайте LC-функцию в рамках ловушки

Все объекты помещенные в стек очистки внутри ловушки должны быть извлечены из стека до выхода за пределы ловушки. Иначе будет сгенерирована паника E32USER-CBase 71.

Будьте осторожны при использовании TRAPD

При каждом использовании TRAPD объявляется переменная которая будет содержать код сброса в случае его возникновения. Рассмотрим фрагмент кода:

TRAPD(err, LeavingFunctionL());
if (!err)
{
TRAPD(err, AnotherLeavingFunctionL());
}
return err;

В результате выполнения данного кода всегда будет возвращаться код сброса функции LeavingFunctionL(), так как повторное использование макроса определит новую переменную err уже в фигурных скобках. Для корректной работы при вызове AnotherLeavingFunctionL() нужно использовать макрос TRAP потому что переменная err уже объявлена.

Оптимизированное использования ловушек

Частое использование ловушек может привести к серьезной потере производительности. Рассмотрим фрагмент кода:

TInt DoSomethingLeaveSafe()
{
TRAPD(err, LeavingFunctionL());
if (!err)
{
TRAP(err, AnotherLeavingFunctionL());
if (!err)
{
TRAP(err, OneMoreLeavingFunctionL());
}
}
return err;
}

В данном случае использование трех ловушек можно свести к одной если добавить дополнительную функцию:

TInt DoSomethingLeaveSafe()
{
TRAPD(err, DoSomethingL());
return err;
}
 
void DoSomethingL()
{
LeavingFunctionL();
AnotherLeavingFunctionL();
OneMoreLeavingFunctionL();
}

Результат будет тот же, но производительность возрастет.

Дополнительные средства при организации ловушек

В файле e32cmn.h (в папке \epoc32\include) можно обнаружить три интересных макроса:

TRAP_INSTRUMENTATION_START TRAP_INSTRUMENTATION_NOLEAVE TRAP_INSTRUMENTATION_LEAVE

Эти макросы позволяют определить код, который будет выполняться во время работы ловушки:

  • TRAP_INSTRUMENTATION_START - перед вызовом сбрасываемого кода
  • TRAP_INSTRUMENTATION_NOLEAVE - выполняется если вызов прошел без сброса
  • TRAP_INSTRUMENTATION_LEAVE - выполняется если был сброс

Для использования этих макросов Вам необходимо переопределить их, например так:

static void LogLeave(TInt aErr, const TUint8* aFile, TInt aLine);
 
#undef TRAP_INSTRUMENTATION_LEAVE
#define TRAP_INSTRUMENTATION_LEAVE(aResult) LogLeave(aResult, (TText8*)__FILE__, __LINE__)

В данном примере функция LogLeave() будет вызываться при каждом пойманном сбросе. Аргументы функции: код сброса, имя исходного файла, номер строки в исходном файле.

В результате работы данной функции может быть сформирована следующая строка:

Leave: -5, somesourcefile.cpp : 307
This page was last modified on 8 December 2011, at 23:31.
277 page views in the last 30 days.

Was this page helpful?

Your feedback about this content is important. Let us know what you think.

 

Thank you!

We appreciate your feedback.

×