Отладка приложений


         

Оригинальный код функции Fire_TraceEvent приведен


Оригинальный код функции Fire_TraceEvent приведен в листинге 11-3. Будьте внимательны при просмотре кода и попробуйте найти ошибку.

Листинг 11-3. Функция Fire_ TraceEvent с ошибкой

HRESULT Fire_TraceEvent( BSTR bstrText )

{

CComVariant varResult;

Т* рТ = static_cast<T*>( this );

int nConnectionlndex;

CComVariant* pvars = new CComVariant[1];

int nConnections = m_vec.GetSize( );

for ( nConnectionlndex = 0;

nConnectionlndex < nConnections; nConnection!ndex++ ) 

{

pT->Lock();

CComPtr<IUnknown> sp = m_vec.GetAt( nConnectionlndex );

pT->Unlock( );

IDispatch* pDispatch = reinterpret_cast<IDispatch*>( sp.p );

if (pDispatch != NULL)

{

VariantClear( SvarResult );

pvars[0] = bstrText;

DISPPARAMS disp = { pvars, NULL, 1, 0 };

pDispatch->Invoke( 0xl,

IID_NULL,

LOCALE_USER_DEFAULT, 

DISPATCH_METHOD,

 &disp, SvarResult, 

NULL, NULL ); 



}

delete[] pvars; 

return varResult.scode; 

}

Имейте в виду, что утверждение срабатывало только тогда, когда программа просмотра к TraceSrv не присоединялась. Внимательно посмотрев на Fire_rraceEvent, вы увидите, что цикл for никогда не выполняется, если программа просмотра не присоединена. Однако сгенерированный код возвращает varResuit.scode, который инициализируется только внутри цикла for. Следовательно, когда программа просмотра не присоединена, функция возвращает неинициализированное значение. В отладочных построениях функция Fire_rraceEvent возвращала значение Охсссссссс (символ-заполнитель, который при компиляции с ключом /GZ помещается в локальные переменные).

Решение проблемы неинициализированной переменной было довольно простым. Я переименовал файл, который генерировала команда Implement Connection Point, (TRACESRVCP.H) в CORRECTEDTRACESRVCP.H и после объявления переменной varResult установил varResuit.scode равным s ок. Хотя использование неинициализированных переменных в практике программирования не рекомендуется, но теперь, по крайней мере, разработчики Visual C++ возвращают результаты вызовов IDispatch:: invoke.В предыдущих версиях Visual C++ это было невозможно. Как только я решил эту маленькую проблему, TraceSrv стал выполняться довольно хорошо.

Прежде чем завершить эту главу, рассмотрим программу TraceView, обеспечивающую безопасность в Win32, и вызовы TraceSrv из пользовательского кода.



Содержание  Назад  Вперед