Rodrigo Strauss :: Blog
C++ com sanidade: fazendo a IDE do Visual Studio.NET trabalhar para você
Uma das coisas mais irritantes que acontecem durante o DEBUG de uma aplicação ATL, é o fato do VS.NET insistir em fazer debug das sobrecargas de operadores dos "SmartTypes" do ATL. Quando você usa "Step Into" (F11) para fazer debug de uma função, você é obrigado a passar por todas as sobrecargas de operadores antes de chegar na função. Como um pedaço de código fonte vale mais do que (e*pi)^3 palavras, vamos ao que interessa:
HRESULT DoTheFlufflers(BSTR str, VARIANT v, IUnknown* pUnk)
{
MessageBox(NULL, str, L"BSTR", MB_OK);
if(v.vt == VT_BSTR)
MessageBox(NULL, v.bstrVal, L"VARIANT", MB_OK);
else
{
MessageBox(NULL,
L"Será que você poderia, por obséqio, colocar uma string nessa Variant?",
L"VARIANT",
MB_OK);
return E_UNEXPECTED;
}
//
// dã!
//
pUnk->AddRef();
pUnk->Release();
return S_OK;
}
int main()
{
HRESULT hr;
CComBSTR str;
CComVariant v;
CComPtr pUnk;
str = L"Eu sou uma string legal, podemos ser amigos?";
v = 0xDEADBEEF;
hr = CoCreateInstance(CLSID_FLUFFLERS, NULL, CLSCTX_ALL, IID_IUnknown, (void**)&pUnk);
if(FAILED(hr))
{
OutputDebugString(L"Eu desisto...");
//
// pena que não funciona em UserMode...
//
// KeBugCheckEx(0xFFFFFFFF,0,0,0,0);
return hr;
}
DoTheFlufflers(str, v, pUnk); // <<-- Muito chato fazer Step Into nessa função...
return 0;
}
Quando você usar o F11 sobre a instrução "DoTheFlufflers(str, v, pUnk);", o VS.NET vai entrar primeiro em "ComPtrBase::operator T*()", depois em "CComBSTR::operator BSTR()", e só depois em "DoTheFlufflers". Se essa função fosse de um objeto COM (algo como "pUnk->DoTheFlufferization(str, v, pUnk)"), você ainda teria chamada de "ComPtrBase::operator ->" antes das outras. Isso realmente é muito chato.
Mas há uma solução para esse problema no VS.NET: Existe a chave [HKEY_CURRENT_USER\\Software\\Microsoft\\VisualStudio7.1\\NativeDE\\StepOver], onde você pode colocar nomes de funções que não terão StepInto. É só criar valores string com um id numérico e com valor "um_regular_expression=NoStepInto". Para ignorar todos os métodos de CComPtr, use algo como ".+CComPtr.+=NoStepInto". A minha configuração por enquanto é essa:
Windows Registry Editor Version 5.00 [HKEY_CURRENT_USER\\Software\\Microsoft\\VisualStudio7.1\\NativeDE\\StepOver] "100"=".+CCom.*Ptr.+=NoStepInto" "99"=".+CComBSTR.+=NoStepInfo" "98"=".+CComVariant.+=NoStepInfo" "97"=".+CAtlMap.*=NoStepInfo" "96"=".+CAutoPtr.+=NoStepInto"
Os valores são avaliados em ordem inversa. Essa configuração pode ser modificada sem reiniciar o VS.NET, parece que ela é recarregada a cada sessão de debug. Para maiores informações sobre esse assunto, dê uma olhada nessa mensagem de alguém da equipe do C#, que mandou um CTRL+C, CTRL+V da única documentação que existe sobre esse recurso: o código fonte da IDE do Visual Studio.NET.
Em 31/03/2005 04:56, por Rodrigo Strauss





A FCL tem alguns recursos interessantes para este cenário em managed code.
Dentro de System.Diagnostics existem diversos atributos que controlam o fluxo de depuração como, pro exemplo, DebuggerHiddenAttribute e DebuggerStepThroughAttribute.
Outra coisa... Os últimos samples estão bem mais legíveis para os não-iniciados. Muito bom!
Existe algum lugar em que se explique a correlação e diferenças entre Win32, COM, ATL, WTL, MFC e outras APIs e/ou frameworks? Fica a sugestão de escrever sobre isto.