Tag Archives: C++

My favorites C++ books

There are various books about C++. The reference manuals and the optimizations ones. For example, Addison Wesley has a serie called “C++ In-Depth – Bjarne Stroustrup” also called the red books. Look at this titles:

  • Accelerated C++: Practical Programming by Example, Andrew Koenig
    and Barbara E. Moo
  • Applied C++: Practical Techniques for Building Better Software, Philip Romanik and Amy Muntz
  • The Boost Graph Library: User Guide and Reference Manual, Jeremy G. Siek, Lie-Quan Lee, and Andrew Lumsdaine
  • C++ Network Programming, Volume 1: Mastering Complexity Using ACE and Patterns, Douglas C. Schmidt and Stephen D. Huston
  • C++ Network Programming, Volume 2: Systematic Reuse with ACE and Frameworks, Douglas C. Schmidt and Stephen D. Huston
  • C++ Template Metaprogramming: Concepts, Tools, and Techniques from Boost and Beyond, David Abrahams, Aleksey Gurtovoy
  • Essential C++, Stanley B. Lippman
  • Exceptional C++ Style 40 New Engineering Puzzles, Programming Problems, and Solutions, Herb Sutter
  • Exceptional C++; 47 Engineering Puzzles, Programming Problems,
    and Solutions, Herb Sutter
  • Modern C++ Design: Applied Generic Programming and Design Patterns,
    Andrei Alexandrescu
  • More Exceptional C++: 40 New Engineering Puzzles, Programming Problems, and Solutions, Herb Sutter

Not in the serie:

  • Effective C++ Third Edition, 55 Specific Ways to Improve Your Programs and Designs, Scott Meyers

The book of the language is:

  • The C++ programming language, Fourth edition, Bjarne Stroustrup

The books to understand rapidly the new features of C++11 is:

  • A Tour of C++, Bjarne Stroustrup
  • C++ Primer, Fifth Edition, Stanley B. Lippman, Josée Lajoie, Barbara E. Moo

The book to understand the compilers is:

  • Inside the C++ Object Model, Stanley B. Lippman

The book to learn the STL:

  • The C++ standard library : a tutorial and reference, 2nd Edition, Nicolai M. Josuttis

Download UltraFluid modeler

You can download my application here:

http://www.windowscpp.com/Appz/UltraFluid_Modeler.zip

In the archive there are 2 main folders: bin and images. I have also created a shortcut. Adjust the shortcut to start the app located in bin but place the working directory on the upper folder.

I have a little bug on displaying images by setting the current folder. It will be fixed sooner.

To run the application, you must have vcredist from VS2015. These dll are not distributed in the zip archive.

ultrafluid_modeler_2

Updating Scintilla open-source project and Naughter’s wrappers and Boost 1.63

When I have updated Scintilla’s wrappers written by Naughter, I encountered compilation errors…
This the MFC class view that operates with the scintilla control. I need to update that class too. But first of all, I need to update Boost. Current version is 1.63. Just compile it with bjam. Classic stuff. Result is in stage\lib folder.

boost_stage_lib_163

For the moment I use Boost only for serialization stuff for XML stuff.

modeler1_saveasxml

Here is a XML file:

modeler1_data_xml

Boost serialization is not easy because it is designed that data has to be read by a Boost app…

Using open-source libraries for MyModeler C++ project

I will make some enhancements to my modeler project (http://ultrafluid.codeplex.com). I have moved to Visual Studio online.

image001

MyModeler

My project use three open-source projects:

– Scintilla (http://www.scintilla.org/)

– MFC Naughter classes to encapsulate Scintilla edit control with MFC (http://www.naughter.com/scintilla.html)

– Boost (http://www.boost.org/)

My project was primary built in the 2012′. It was an idea to make my daughter Lisa able to place elements with the mouse.
It is a family project. It was also an free-time occupation when I was consultant for the “Banque de France” to build Architecture diagrams.
The initial goal of the project is to build diagrams with individual shapes elements. These elements contains properties and everything is store in a database.
Then, it is possible to make requests to find things. For the moment, I have no database. I need to implement that part of the software.

First surprise when I rebuilt the project with the latest version of Scintilla, the Naughter classes produced C++ compilation errors.
I needed to get the latest classes but also make some minor corrections (hide the code of 2 methods).
For boost, I have a version 1.59 on my computer and I have no evidence to jump to the latest version because I just use serialization and XML stuff which belong to a very stable library : serialization.

I rebuilt the project and it just works. The project updated to MSVC140 build tools with Visual Studio 2015.
This is the magic of C++ : it works along all theses years… But my open-source libraries has evolved and most of the time, getting an updated version can bring some changes.
In my case, the Naughter MFC classes depends on Scintilla project so the GET operation must assure that the 2 projects are synced.

Using log4cpp with Visual Studio 2015

First, let’s download log4cpp from sourceforge: http://log4cpp.sourceforge.net/

Log4cpp version is log4cpp-1.1.2rc5.

Let’s open log4cpp-1.1.2rc5log4cppmsvc10log4cpplog4cpp.vcxproj in VS2015. Try to build it. It fails. 2 errors…

snprintf & vsnprintf stuff. Ugly & cryptic error. Multiples definitions of body…

Let’s dive in the source code and we can see that a preprocessor declaration will help us.

Add HAVE_SNPRINTF to the project settings in preprocessor stuff. Build it. It is ok.

1> Creating library Debuglog4cpp.lib and object Debuglog4cpp.exp

1> log4cpp.vcxproj -> D:Devcpplog4cpp-1.1.2rc5log4cppmsvc10log4cppDebuglog4cpp.dll

========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========

Now, let’s build a sample client for using this dll.

We add a Win32 console project to the solution.

Add include folder to the client project:

Add the library folder to find the .lib file:

Add in your stdafx.h the following code:

#pragma once

#include "targetver.h"

#include <stdio.h>

#include <tchar.h>

#include <string>

#include <iostream>

using namespace std;

#include <log4cpp/RollingFileAppender.hh>

#include <log4cpp/Category.hh>

#include <log4cpp/Configurator.hh>

#include <log4cpp/Portability.hh>

#include <log4cpp/PropertyConfigurator.hh>

#pragma comment(lib, "log4cpp.lib")

The main program just put some data in file:

#include "stdafx.h"

#include "Logger.h"

int main()

{

MyLogger log;

if (!log.Init())

return 0;

log.LogDebug("Enter main...");

log.LogInfo("Main...");

log.LogDebug("Exit main");

return 0;

}

All the magic is contained in this code snipet:

#pragma once

class MyLogger

{

public:

MyLogger()

{

}

virtual ~MyLogger()

{

log4cpp::Category::shutdown();

}

bool Init()

{

try

{

string initFileName = "log4cpp.property";

log4cpp::PropertyConfigurator::configure(initFileName);

}

catch (log4cpp::ConfigureFailure& f)

{

std::cout << "Configure Problem" << f.what() << std::endl;

return false;

}

return true;

}

void LogDebug(string message)

{

log4cpp::Category & mylogger = log4cpp::Category::getInstance("MyLogger");

mylogger.debug(message);

}

void LogInfo(string message)

{

log4cpp::Category & mylogger = log4cpp::Category::getInstance("MyLogger");

mylogger.info(message);

}

};

The configuration file is defined like:

#file log4cpp.property

log4cpp.rootCategory=DEBUG, rootAppender

log4cpp.category.MyLogger=DEBUG, aLogger

log4cpp.appender.rootAppender=ConsoleAppender

log4cpp.appender.rootAppender.layout=BasicLayout

log4cpp.appender.aLogger=RollingFileAppender

log4cpp.appender.aLogger.fileName=c:tempaLogger.log

log4cpp.appender.aLogger.maxFileSize=10240

log4cpp.appender.aLogger.maxBackupIndex=5

log4cpp.appender.aLogger.layout=PatternLayout

log4cpp.appender.aLogger.layout.ConversionPattern=[%d{%H:%M:%S,%l}] %m%n

#end of file

A WMI Wrapper for C++… Easy !

Imagine you want to explore the world of WMI with C++ like that:

 ManagementClass mc(_TEXT("Win32_NetworkAdapter"));
 bool result = mc.GetInstances();
 while (mc.MoveNext())
 {
  CNetworkCard card;
  card.m_Name = mc.GetStringProperty(_TEXT("Name"));
  card.m_MACAddress = mc.GetStringProperty(_TEXT("MACAddress"));
  card.m_Speed = mc.GetStringProperty(_TEXT("Speed"));
  m_data.m_NetworkCards.Add(card);
 }

Here is the class you need:


class ManagementClass
{
public:
ManagementClass(const CString& adr);
~ManagementClass();

bool GetInstances();
bool MoveNext();
CString GetStringProperty(CString propName);
bool GetBoolProperty(CString propName);
int GetIntProperty(CString propName);
long GetLongProperty(CString propName);

protected:
CString m_wmiAdr;
IWbemLocator *m_pLoc;
CComPtr<IWbemServices> m_pSvc;
CComPtr<IEnumWbemClassObject> m_pEnumerator;
CComPtr<IWbemClassObject> m_pclsObj;
};

The implementation is a little by tricky. Look:


#include "stdafx.h"
#include "ManagementClass.h"
ManagementClass::ManagementClass(const CString& adr)
{
m_wmiAdr.Format(_TEXT("SELECT * From %s"), adr);
m_pLoc = nullptr;
m_pEnumerator = nullptr;
m_pclsObj = nullptr;
}
ManagementClass::~ManagementClass()
{
if (m_pLoc)
{
m_pLoc->Release();
m_pLoc = nullptr;
}
}

bool ManagementClass::GetInstances()
{
static bool bSecurity = false;

HRESULT hres;

if (bSecurity == false)
{
bSecurity = true;

hres = CoInitializeSecurity(
NULL,
-1,                          // COM authentication
NULL,                        // Authentication services
NULL,                        // Reserved
RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication
RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation
NULL,                        // Authentication info
EOAC_NONE,                   // Additional capabilities
NULL                         // Reserved
);
}

hres = CoCreateInstance(
CLSID_WbemLocator,
0,
CLSCTX_INPROC_SERVER,
IID_IWbemLocator, (LPVOID *)&m_pLoc);
if (FAILED(hres))
{
return false;
}

// Connect to WMI through the IWbemLocator::ConnectServer method
// Connect to the root\cimv2 namespace with
// the current user and obtain pointer pSvc
// to make IWbemServices calls.
hres = m_pLoc->ConnectServer(
_bstr_t(L"ROOT\\CIMV2"), // Object path of WMI namespace
NULL,                    // User name. NULL = current user
NULL,                    // User password. NULL = current
0,                       // Locale. NULL indicates current
NULL,                    // Security flags.
0,                       // Authority (e.g. Kerberos)
0,                       // Context object
&m_pSvc                    // pointer to IWbemServices proxy
);

if (FAILED(hres))
{
m_pLoc->Release();
return false;                // Program has failed.
}

hres = CoSetProxyBlanket(
m_pSvc,                        // Indicates the proxy to set
RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx
RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx
NULL,                        // Server principal name
RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx
RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
NULL,                        // client identity
EOAC_NONE                    // proxy capabilities
);

if (FAILED(hres))
{
m_pLoc->Release();
return false;
}

// Use the IWbemServices pointer to make requests of WMI ----

// For example, get the name of the operating system
//IEnumWbemClassObject* pEnumerator = NULL;
//CComPtr<IEnumWbemClassObject> pEnumerator = NULL;
hres = m_pSvc->ExecQuery(
bstr_t("WQL"),
bstr_t((LPTSTR)(LPCTSTR)m_wmiAdr),
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&m_pEnumerator);

if (m_pEnumerator == NULL)
{
return false;
}

if (FAILED(hres))
{
m_pLoc->Release();
return false;
}

return true;
}

bool ManagementClass::MoveNext()
{
ULONG uReturn = 0;
if (m_pEnumerator)
{
CComPtr<IWbemClassObject> pclsObj = nullptr;
HRESULT hr = m_pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
if (hr == S_FALSE)
{
return false;
}

m_pclsObj = pclsObj;
}
else
{
return false;
}

return true;
}

CString ManagementClass::GetStringProperty(CString propName)
{
ASSERT(m_pclsObj != NULL);
CComVariant vtProp;
HRESULT hr = m_pclsObj->Get(propName, 0, &vtProp, 0, 0);
CString data;
AfxBSTR2CString(&data, vtProp.bstrVal);
return data;
}

bool ManagementClass::GetBoolProperty(CString propName)
{
ASSERT(m_pclsObj != NULL);
bool result = false;
CComVariant vtProp;
HRESULT hr = m_pclsObj->Get(propName, 0, &vtProp, 0, 0);
if (vtProp.boolVal == 1)
result = true;
return result;
}

int ManagementClass::GetIntProperty(CString propName)
{
ASSERT(m_pclsObj != NULL);
CComVariant vtProp;
HRESULT hr = m_pclsObj->Get(propName, 0, &vtProp, 0, 0);
int i = vtProp.iVal;
return i;
}

long ManagementClass::GetLongProperty(CString propName)
{
ASSERT(m_pclsObj != NULL);
CComVariant vtProp;
HRESULT hr = m_pclsObj->Get(propName, 0, &vtProp, 0, 0);
long l = vtProp.lVal;
return l;
}

Don’t forget the include stuff in the stdafx.h:

#include <Wbemidl.h>

#pragma comment(lib, “wbemuuid.lib”)

WRL component with support for Event handlers

The WRL sample is updated to support event handling on a WinRT component.

It requires a special delegate type in the IDL file.

// Library1.IDL
import "inspectable.idl";
import "Windows.Foundation.idl";

#define COMPONENT_VERSION 1.0

namespace Library1
{
    interface ILogger;
    runtimeclass Logger;

    [uuid(1FCD374B-2C3C-49E3-93A7-6FB801080D45), version(COMPONENT_VERSION)]
    delegate HRESULT LoggerEventHandler([in] HSTRING e);

    [uuid(3EC4B4D6-14A6-4D0D-BB96-31DA25224A15), version(COMPONENT_VERSION)]
    interface ILogger : IInspectable
    {
        HRESULT LogInfo([in] HSTRING value);
        [eventadd] HRESULT LoggerChanged([in] LoggerEventHandler* handler, [out][retval] EventRegistrationToken* token);
        [eventremove] HRESULT LoggerChanged([in] EventRegistrationToken token);
    }

    [version(COMPONENT_VERSION), activatable(COMPONENT_VERSION)]
    runtimeclass Logger
    {
        [default] interface ILogger;
    }
}

Sample updated : http://code.msdn.microsoft.com/windowsapps/Windows-Runtime-Component-4dc6fa20