traps and pitfalls for vc6 atl c
Skip this Video
Download Presentation
Traps and pitfalls for VC6, ATL, C++

Loading in 2 Seconds...

play fullscreen
1 / 23

Traps and pitfalls for VC6, ATL, C - PowerPoint PPT Presentation

  • Uploaded on

Traps and pitfalls for VC6, ATL, C++. May be obvious ? May be not ? Mark Bartosik. Danagers of _bstr_t. _bstr_t::_bstr_t(const char * narrow_str) Unhandled exception 0xC00000FD because it allocates from the stack 2 x strlen(narrow_str) operator const char *() const operator char *()

I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
Download Presentation

PowerPoint Slideshow about 'Traps and pitfalls for VC6, ATL, C' - chung

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.

- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
traps and pitfalls for vc6 atl c
Traps and pitfalls for VC6, ATL, C++
  • May be obvious ?
  • May be not ?

Mark Bartosik

danagers of bstr t
Danagers of _bstr_t
  • _bstr_t::_bstr_t(const char * narrow_str)
    • Unhandled exception 0xC00000FDbecause it allocates from the stack 2 x strlen(narrow_str)
  • operator const char *() constoperator char *()
    • both return a pointer to PRIVATE data

const char * p = get_str();

unsigned len = strlen(p); // bang ???#! error ??

danagers of bstr t1
Danagers of _bstr_t
  • operator const wchar_t *() constoperator wchar_t *()
    • both return a pointer to PRIVATE data

BSTR p = get_str();

unsigned len = SysStringLen(p); // bang ???#! err??

alternatives with bstr t
Alternatives with _bstr_t
  • const wchar_t * GetWString() const
  • const char * GetString() const
  • But not realistic. Once the extraction operators exist, you cannot avoid them.
  • #pragma depracatedsee Visual Studio .NET
dangers of ccombstr
Dangers of CComBSTR
  • What is wrong with the following member functions?operator BSTR() constBSTR* operator&()
  • int a;int * p = &a;
ccomptr t ccomqiptr t
CComPtr<T> CComQIPtr<T>
  • T** operator&()
    • Gives access to internal datacan cause a leak (if not NULL)
  • T& operator*()
    • Does not access to IUnknownoperator->() returns proxy object with private IUnknown
  • operator T*()
    • Gives implicit access to raw pointer
com ptr t t
  • T** operator&()
  • T* operator->()Exposes Iunknown, unlike CComPtr & CComQIPtr which return a proxy object
  • Behaves like CComQIPtr but uses exceptions for error reporting.Auto declared by #import
how to choose
How to choose ?
  • Consistency is best
  • Consistently use _bstr_t or CComBSTR
  • Consistently use CComPtr or _com_ptr_tIf using #import prefer _com_ptr_t
  • Does the rest of your code use exceptions or magic return values?
  • Write your own? (based on CComPtr)

std::map<unsigned, employee_t>std::map<unsigned, CComPtr<IEmployee> >std::map<unsigned, CAdapt<CComPtr<IEmployee> > >

Also when erasing elements, don’t saw off the branch that you are sitting on. (General STL rule)Store objects NOT dumb pointers (smart pointers are objects)Remember that my_collection.erase(iter) invalidates iter.use iter = my_collection.erase(iter)Don’t forget about the algorithms #include <algorithm>

  • Can use instead of .h, even for implementationImplement the raw_ functions.
  • Read the .tlh filesBe careful some functions will return IDispatchPtr others will return IDispatch *. It depends on the IDL.Reading the .tlh is a thinking aid, keep it open in a window.
  • Prefer __stdcall over __thiscall
  • Optimizer off
  • Consider releasing with optimizer off (except allow inlines for likes of STL)
  • Symbol files on (PDB not PDB for edit continue), Link with debug info,Do not separate types
  • Debug with Visual Studio .NET
more lifetime management
(more) lifetime management

CObj::foo(){ CSLock __anonymous__(m_critsec); m_sub_object.Release();} // Bang!

CObj::foo(){ IUnknownPtr __anonymous__(this); CSLock __anonymous__(m_critsec); m_sub_object.Release();}

more lifetime management1
(more) lifetime management
  • Do not mix strong and weak pointers
  • What if you need a C++ pointer to a CComObject derived object?std::pair<COurClass*, UnknownPtr> orstruct
  • {
  • UnknownPtr strong_ref; COurClass * weak_ref;
  • }
  • Avoid Singleton anti-pattern
  • Once per what?Per network? Per sub-net? Per machine? Per apartment ? Per security context ? Per process? Per thread? Per transaction? Per user ? Etc.The ATL singleton is once per process.
  • Use a more natural language idiom
    • C++ globals are naturally per process.
    • C variables in a shared data seg are naturally per machine
    • VB module variables are naturally per thread (apartment)
    • But avoid global pointers to COM objects (issues with CRT and COM initialization order)
cyclic references connection points
Cyclic references & Connection points
  • Wizard generated code is just bad (has some bugs)Also it is synchronoussee (search for Bartosik)
  • Lack of type safety (IDispatch)
build consideration
Build consideration
  • Prefer dynamic link CRT(but there are install issues)
  • Avoid creating COM components within a group
  • STL
  • WTL
leak browser
Leak Browser
  • Much of COM is about ownership / lifetime management, but poor C++ language binding, thus the bugs.
  • Will find all your leaks
  • Soon will find all your references to deleted objects
  • Soon will find all use of uninitialized memory
  • Contact Bartosik for updates / latest build.

reinterpret_cast<TO>(from)reinterpret the bit pattern (unsafe and forceful)


runtime check (from must have at least one virtual function). Often a sign ofbad design. Why don’t you know the type. dynamic_cast<derived*>(base*)

static_cast<TO>(from)convert only if reasonable

const_cast<TO>(from)remove either const or volatile qualifiers

(TO)c-style cast -- avoid it, like static_cast OR reinterpret_cast optionally combined with const_cast, and can be more forceful than reinterpret_cast.