Category Archives: C++/CLI

C++ Code: A lightweight Version Comparison class

This class is used for comparing version info in the form of "Major.Minor.Revision.Build".


// VersionInfo.h - Declararion of CVersionInfo 

class CVersionInfo
{
public:
    CVersionInfo(wstring s);
    CVersionInfo(unsigned int major,
    unsigned int minor,
    unsigned int revision,
    unsigned int build);

public: 
    wstring to_string() const;
    bool operator< (const CVersionInfo& vi);
    bool operator> (const CVersionInfo& vi);
    bool operator== (const CVersionInfo& vi);

private:
    unsigned int m_major;
    unsigned int m_minor;
    unsigned int m_revision;
    unsigned int m_build;
};


// VersionInfo.cpp - implementations of CVersionInfo 

CVersionInfo::CVersionInfo(unsigned int major,
        unsigned int minor, 
        unsigned int revision,
        unsigned int build)
        :m_major(major)
        ,m_minor(minor)
        ,m_revision(revision)
        ,m_build(build)
{} 

CVersionInfo::CVersionInfo(std::wstring s)
        :m_major(0)
        ,m_minor(0)
        ,m_revision(0)
        ,m_build(0)
{
    vector<wstring> vS;
    wstringstream ss;
    boost::algorithm::split(vS, s, boost::algorithm::is_any_of(L".")); 

    switch(vS.size())
    {
        case 4:
            ss.str(vS[3]); ss>>std::hex>>m_build; ss.clear();
        case 3:
            ss.str(vS[2]); ss>>std::hex>>m_revision; ss.clear();
        case 2:
            ss.str(vS[1]); ss>>std::hex>>m_minor; ss.clear();
        case 1:
            ss.str(vS[0]); ss>>std::hex>>m_major; ss.clear();
        default:
            ;
    }
} 

bool CVersionInfo::operator< (const CVersionInfo& vi)
{
    if(m_major != vi.m_major) return m_major < vi.m_major; 
    if(m_minor != vi.m_minor) return m_minor < vi.m_minor; 
    if(m_revision != vi.m_revision) return m_revision < vi.m_revision; 
    if(m_build != vi.m_build) return m_build < vi.m_build; 

    return false;
} 

bool CVersionInfo::operator> (const CVersionInfo& vi)
{
    if(m_major != vi.m_major) return m_major > vi.m_major; 
    if(m_minor != vi.m_minor) return m_minor > vi.m_minor; 
    if(m_revision != vi.m_revision) return m_revision > vi.m_revision; 
    if(m_build != vi.m_build) return m_build > vi.m_build; 

    return false;
} 

bool CVersionInfo::operator== (const CVersionInfo& vi)
{
    if((m_major == vi.m_major) 
        && (m_minor == vi.m_minor)
        && (vi.m_revision == vi.m_build)) 
        return true; 

    return false;
} 

wstring CVersionInfo::to_string() const
{
    wstringstream ss; 

    ss << m_major
       << L"."
       << m_minor
       << L"."
       << m_revision
       << L"."
       << m_build; 

    return ss.str();
}

UNICODE/Wide Characters handling in C++

I was bitten again.

Life was never meant to be easier, and it’s tougher when you come to deal with wide characters in C++ with wfstream, wcout or any other WIDE versions of standard I/O facilities.

Two Rule of Thumbs:

#1 Unicode files must be opened as binary

Example:

std::wifstream xmlFile(m_FileName, ios::binary);

std::wofstream xmlFile(m_FileName, ios::binary);

#2 when working with languages other than English, wifstream/wofstream must be imbued with a non-default facet to read from or write to a real UNICOE file, or else wofstream ends up writing an ANSI file.

An explanation is available from here .

Example:

  1:  wstring ws(L"this is a wide string"); 
  2:  wofstream of_imbued;
  3: 
  4:  IMBUE_NULL_CODECVT(of_imbued); 
  5: 
  6:  of_imbued.open(L"c:\\imbued.txt", ios::binary);
  7:  of_imbued<<ws.c_str(); 
  8: 
  9:  wofstream of_not_imbued;
 10:  of_not_imbued.open(L"c:\\not_imbued.txt", ios::binary);
 11:  of_not_imbued<<ws.c_str();
 12: 

Outputs of the above code:

Two imbue facilities are available:

Boost Library

imbue_null_codecvt (the one used in above example)

There’s also a classical  C way to write UNICODE files:

  1: wchar_t myWString[] = L"Some strange characters." 
  2: fwrite(myWString, sizeof(wchar_t), sizeof(myWString)/sizeof(wchar_t), 
  3: myFile ); 

However, it is not portable.

References:

  1. Unicode Implementation

http://groups.google.com/group/comp.lang.c++.moderated/browse_thread/thread/ffe0912d1462d7a5/7601a62008fdd25a?lnk=st&q=wfstream+fstream+cout+wcout&rnum=6&hl=en#7601a62008fdd25a

  1. Unicode in C++

http://groups.google.com/group/comp.lang.c++/browse_thread/thread/f4a6a434b0453187/1edc2bc1f4187597?lnk=st&q=wfstream+fstream+cout+wcout&rnum=3&hl=en#1edc2bc1f4187597

  1. how to read a Unicode file with fstream?

http://groups.google.com/group/microsoft.public.vc.stl/browse_thread/thread/45d7520ec3ad3f51/d57b41e9abb20117?lnk=st&q=wfstream+fstream+cout+wcout&rnum=2&hl=en#

  1. A very puzzling problem: cout vs. wcout, fstream vs. wfstream

http://groups.google.com/group/comp.lang.c++.moderated/browse_thread/thread/37c3e24861ca09e3/78fe0aeed7b728de?lnk=st&q=wfstream+fstream+cout+wcout&rnum=1&hl=en#78fe0aeed7b728de

  1. Upgrading an STL-based application to use Unicode

http://www.codeproject.com/vcpp/stl/upgradingstlappstounicode.asp

VLD – Enhanced Memory Leak Detection for Visual C++

A handy and must have tool.

http://www.codeproject.com/tools/visualleakdetector.asp

http://www.testage.net/AutoTest/Opentest/200609/896.htm

one things though, to compile from the source code( which you surely want to),  one must download the latest version of "Debugging Tools for Windows" from http://www.microsoft.com/whdc/devtools/debugging/default.mspx because those header files and dlls shipped with WinXP are way too old.  

Vista APIs for C++

relationship between a ref and pointer in C++

"The obvious implementation of a reference is as a (constant) pointer that is dereferenced each
time it is used. It doesn’t do much harm thinking about references that way, as long as one remembers that a reference isn’t an object that can be manipulated the way a pointer is"

Bjarne – "TCPL 3rd Ed"

How to use app.config files in Visual C++ 2005 projects

from Marcus’s Blog

For most Visual Studio .NET language integrations, app.config files are treated specially. Before the target application is started, (with or without a debug session), the language package ensures that the app.config file is automatically copied to the target application’s configuration file. Visual C++ does not have this feature, however it is easy to get the same:

Add a file named app.config to a Visual C++ project and choose the following project settings:

Command line: type app.config > "$(TargetPath).config"

Description: "Updating target’s configuration file"

Outputs: "(TargetPath).config"

Notice that the file is copied via the command type and piping. I prefer this to using the copy command here, because this command ensures that the date of the compiled file is automatically adapted whenever the file is copied.