×
Namespaces

Variants
Actions

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

From Nokia Developer 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.
79 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.

×