logo
Contato | Sobre...        
rebarba rebarba

Rodrigo Strauss :: Blog

follow us in feedly

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


  
 
 
Comentários
Alfred Gary Myers Jr. | website | em 31/03/2005 | #
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.
Rodrigo Strauss | website | em 31/03/2005 | #
Eu já tinha visto algo sobre isso em .NET, algumas classes geradas pelo VS.NET (DataSet Tipado??) usam esses atributos para evitar esses aborrecimentos que eu falei. Esses dois enfoques tem vantagens e desvantagens. Pelo menos o enfoque .NET é documentado... :-)

Quanto à legibilidade, eu tenho me esforçado para isso, justamente para mostrar que C++ não é coisa do outro mundo.

Nunca vi nada sobre as diferenças entre as sopas de letrinhas. É realmente uma boa sugestão.
Rodrigo Strauss | website | em 31/03/2005 | #
Achei algo que ajuda a explicar a sopa de letrinhas (apesar de não ser esse o objetivo do artigo):

http://www.msversus.org/title/What's+The+Need+For+.NET%3F
Nonaka | e-mail | em 30/04/2015 | #
Nossa se eu soubesse isso antes :)!
Algo a dizer?
Nome:


Site:


E-mail:


Escreva o número vinte e seis:


 Não mostre meu e-mail no site, não serve pra nada mesmo...

Comentário





Os comentários devem ser sobre assuntos relativos ao post, eu provavelmente apagarei comentários totalmente offtopic. Se quiser me enviar uma mensagem, use o formulário de contato. E não esqueça: isso é um site pessoal e eu me reservo o direito de apagar qualquer comentário ofensivo ou inapropriado.
rebarba rebarba
  ::::