2010-09-27 2 views
0

Мне пришлось определить новый набор оболочек для существующих методов. Эти новые обертки намерены помочь в отладке, включив определенную информацию трассировки.Связывание вызовов метода

Оригинальный код Источник:

sample.c ::

Caller{ 

void functionA(){ 
    funcB(); 
} 

} 

Callee{ 

void funcB(){ 
} 
} 

Модифицированный код с традиционным Упаковочный Функциональность:

Sample.h ::

#define funcB wrapperFuncB //not visible to Callee 

Caller{ 

void functionA(){ //this gets redirected to wrapperFuncB cos of #define 
    funcB(); 
} 
} 
Callee{ 

void wrapperFuncB(){ 
    if(DEBUG){ //value of DEBUG is set at runtime 
     //COLLECT Trace data 


    }else{ 
     funcB(); 
    } 
} 
void funcB(){ 
} 
} 

Этот механизм имеет дополнительные накладные расходы: 1] Все вызовы funcB являются ro пространяется к wrapperFuncB, irrespecitve отладочных включен или нет 2] Дополнительный способ кадра [wrapperFuncB] должен быть создан, irrespecitve отладочных включен или нет 3] Накладные условного проверки

+2

Хорошо для вас. У вас есть вопрос ? – ereOn

+0

Это не похоже на C. Тег удален. – pmg

ответ

1

Если методы являются идентичными, вы могли бы использовать что-то вроде этого:

#ifdef __DEBUGING 
#define myClass debug_class 
#else 
#define myClass actual_class 
#endif 

Таким образом, вы можете выборочно выбрать, какой класс вы используете в вашем коде, фактический один или обертку один. Однако может быть несколько проблем, потому что это была первая идея, которая пришла на ум.

1

В качестве альтернативы вы можете поместить отладочные как этот

#ifdef DEBUG_ENABLE 
DEBUG_LOG(X) printf(x) 
#else 
DEBUG_LOG(X) do{}while(0) 

void FunctionA() 
{ 
DEBUG_LOG("\n Debugging function",__func__); 
} 

Вы можете использовать ту же самую процедуру без оберток. Преимущество было бы в том, что журналы могли бы немного облегчить понимание кода, и вы можете включить и отключить их с помощью параметров компилятора.

+0

Вы должны использовать блок do/while для случая #ifdef, а также #else. Возможно, вы ответили, в то время как тег C все еще был в вопросе, настолько справедливым с использованием printf(), хотя с одним аргументом string сложно использовать. В C++ можно использовать 'std :: cerr << __FILE__ << ':' << __LINE << '' << X << '\ n';' или аналогичный, затем 'DEBUG_LOG (« x »<< x) ; и т. д. –

+0

Но проблема здесь: «DEBUG_ENABLE» устанавливается во время выполнения во время фактического выполнения программы. Во время компиляции мы не знаем, будет ли программа выполняться в режиме отладки или нет. – user170008

+0

В этом случае вы узнаете, установлен ли параметр debug_enable или нет, макрос может иметь оператор условного if (debug_enable) и выполнять действие. Это позволяет избежать использования функций обертки. –

0

Как функция wrapperFuncB будет иметь ту же подпись, что и funcB, вы можете просто сделать это без необходимости в новом классе.

#ifdef __DEBUG__ 
#define funcB wrapperFuncB 
#else 
#define funcB actualFuncB 
#end 

поэтому, когда вы не отладки или сбора информации трассировки, вы можете просто отключить его, не определяя DEBUG и не будет никаких накладных расходов

Edit: Обновленный после получения замечаний от user170008

Я не думаю, что #ifdef __DEBUG__ вещь может быть использована во время выполнения. Скорее всего, вам придется полагаться на параметры командной строки, чтобы различать отладочный или обычный прогон. Но что когда-нибудь, как вы используете только создать указатель на функцию и установить его в соответствии с видом бега вы делаете например

void (*funcB)(void); 
if(debug) 
    funcB=debugFuncB; 
else 
    funcB=actualFuncB; 

после этого вы можете просто использовать funcB, как вы используете сейчас funcB то есть();

+0

Но проблема здесь: «__DEBUG__» устанавливается во время выполнения, во время фактического выполнения программы. Во время компиляции мы не знаем, будет ли программа выполняться в режиме отладки или нет. – user170008

+0

, тогда я думаю, вы можете использовать указатели на функции. Я собираюсь добавить к моему ответу – binW