Microsoft KB Archive/320485

= BUG: UNICODE Build of Default ATL Project with Performance Monitor Support Fails =

Article ID: 320485

Article Last Modified on 4/29/2003

-

APPLIES TO


 * Microsoft Visual C++ .NET 2002 Standard Edition
 * Microsoft Visual C++ .NET 2003 Standard Edition

-



This article was previously published under Q320485



SYMPTOMS
When you add an ATL Performance Monitor object to a default ATL project that uses attributes, and the character set of the project is changed to Unicode, the build fails and you receive error C2440 as follows:

'return' : cannot convert from 'char [20]' to 'LPCTSTR'



CAUSE
The attribute provider does not accept a Unicode string, either as _T(&quot;xxx&quot;) or _L(&quot;xxx&quot;), and the Performance Monitor macros do not always convert a string to Unicode.



RESOLUTION
To work around this problem, do not to use attributes for a Unicode build of this kind of project. You must redefine three macros if you want to use these attributes. To avoid changing the atlperf.h header, redefine these macros in the header file for the Performance Monitor object of the project, as follows:

The BEGIN_PERF_MAP macro defines a function that is named GetAppName that directly returns the AppName parameter that is passed to the macro. To work around this problem, return a created CString object instead, so that the following line:

return AppName; is returned as follows: return CString(AppName); The following is the full redefinition for BEGIN_PERF_MAP, together with the #undef for the original code for your reference.

NOTE: However, if you copy and paste from this article, formatting problems may cause compile errors. Microsoft recommends that you copy these macros from atlperf.h, paste them into your source file, and then make the changes as suggested.


 * 1) undef BEGIN_PERF_MAP

private: \ LPCTSTR GetAppName const throw { return CString(AppName); } \ HRESULT CreateMap(WORD wLanguage, HINSTANCE hResInstance, UINT* pSampleRes = NULL) throw \ { \            CPerfMon* pPerf = this; \ (void)pPerf; \ wLanguage; \ hResInstance; \ if (pSampleRes) \ *pSampleRes = 0; \ CString strName; \ CString strHelp; \ HRESULT hr; \ (void)hr; \ ClearMap; The DECLARE_PERF_OBJECT_EX macro uses the raw namestring and helpstring objects that are passed to the macro. Convert these to Unicode by wrapping them in CString objects. The lines that read as follows:
 * 1) define BEGIN_PERF_MAP(AppName) \

strName = (LPCTSTR) namestring; \ strHelp = (LPCTSTR) helpstring; \ must be changed to the following:

strName = CString(namestring); \ strHelp = CString(helpstring); \ The following is the complete DECLARE_PERF_OBJECT_EX macro:
 * 1) undef DECLARE_PERF_OBJECT_EX

static HRESULT RegisterObject(CPerfMon* pPerf, WORD wLanguage, HINSTANCE hResInstance, UINT* pSampleRes) throw \ { \            CString strName; \ CString strHelp; \ HRESULT hr; \ _ATLTRY \ { \                __pragma(warning(push)); \ __pragma(warning(disable: 4127)); \ if (IS_INTRESOURCE(namestring)) \ { \                    ATLASSERT(IS_INTRESOURCE(helpstring)); \ if (pSampleRes) \ *pSampleRes = (UINT) (UINT_PTR) namestring; \ if (hResInstance && !strName.LoadString(hResInstance, (UINT) (UINT_PTR) namestring, wLanguage)) \ return E_FAIL; \ if (hResInstance && !strHelp.LoadString(hResInstance, (UINT) (UINT_PTR) helpstring, wLanguage)) \ return E_FAIL; \ } \                else \ { \                    ATLASSERT(!IS_INTRESOURCE(helpstring)); \ strName = CString(namestring); \ strHelp = CString(helpstring); \ } \                __pragma(warning(pop)); \ } \            _ATLCATCHALL \ { \                return E_FAIL; \ } \            hr = pPerf->AddObjectDefinition(dwObjectId, strName, strHelp, detail, defcounter, instanceless, (ULONG) structsize, maxinstnamelen); \ if (FAILED(hr)) \ return hr; \ return S_OK; \ } \        /* NOTE: put a semicolon after your call to DECLARE_PERF_OBJECT*(...) */ \ /* You must have this for the code wizards to parse things properly */ \ static const DWORD kObjectId = dwObjectId The DEFINE_COUNTER_EX macro is similar to DECLARE_PERF_OBJECT_EX, and the workaround is the same. The following is the complete macro:
 * 1) define DECLARE_PERF_OBJECT_EX(dwObjectId, namestring, helpstring, detail, instanceless, structsize, maxinstnamelen, defcounter) \


 * 1) undef DEFINE_COUNTER_EX

CAssertValidField< (countertype) & ATLPERF_SIZE_MASK >::AssertValidFieldType( &_PerfCounterClass::member ); \ _ATLTRY \ { \                __pragma(warning(push)); \ __pragma(warning(disable: 4127)); \ if (IS_INTRESOURCE(namestring)) \ { \                    ATLASSERT(IS_INTRESOURCE(helpstring)); \ if (hResInstance && !strName.LoadString(hResInstance, (UINT) (UINT_PTR) namestring, wLanguage)) \ return E_FAIL; \ if (hResInstance && !strHelp.LoadString(hResInstance, (UINT) (UINT_PTR) helpstring, wLanguage)) \ return E_FAIL; \ } \                else \ { \                    ATLASSERT(!IS_INTRESOURCE(helpstring)); \ strName = CString(namestring); \ strHelp = CString(helpstring); \ } \                __pragma(warning(pop)); \ } \            _ATLCATCHALL \ { \                return E_FAIL; \ } \            hr = pPerf->AddCounterDefinition(dwCounterId, strName, strHelp, detail, countertype, maxcountersize, (ULONG) offsetof(_PerfCounterClass, member), defscale); \ if (FAILED(hr)) \ return hr;
 * 1) define DEFINE_COUNTER_EX(member, dwCounterId, namestring, helpstring, detail, countertype, maxcountersize, defscale) \



STATUS
Microsoft has confirmed that this is a bug in the Microsoft products that are listed at the beginning of this article.



Steps to Reproduce the Behavior

 * 1) Create a default ATL application. By default, this uses attributed code and the MBCS character set.
 * 2) Add an instance of the ATL Performance Monitor Object.
 * 3) Build the project. Notice that it builds correctly.
 * 4) In Solution Explorer, right-click the project, and then click Properties.
 * 5) Under Configuration Properties, click General, and then in the right pane under Project Defaults, change the Character Set from Use Multi-Byte Character Set to Use Unicode Character Set.
 * 6) Rebuild the project. Note that it fails with error C2440.

Additional query words: Unicode PerfMon attributes CPerfMon

Keywords: kbbug kbunicode kbpending KB320485

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.