<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;CkYARXg6fCp7ImA9WhRbEU8.&quot;"><id>tag:blogger.com,1999:blog-4912226416400969049</id><updated>2012-02-01T18:15:44.614Z</updated><category term="logging" /><category term="Python" /><category term="NMAKE" /><category term="Visual Studio" /><category term="SMB" /><category term="C" /><category term="PyWin32" /><category term="WinDbg" /><category term="map" /><category term="Windows" /><category term="Security" /><category term="TCP/IP" /><category term="Guththila" /><category term="GUI" /><category term="string" /><category term="C++" /><category term="PyDev" /><category term="Resources" /><category term="Axis2C" /><category term="environment variables" /><category term="Networking" /><category term="makefile" /><category term="Debugging" /><category term="manipulator" /><category term="functor" /><category term="NetBIOS" /><category term="Design Patterns" /><category term="Web Services" /><category term="DLL" /><category term="multithreading" /><category term="UML" /><category term="XML" /><category term="Taskbar" /><category term="IIS" /><category term="Batch file" /><category term="wxPython" /><category term="SOAP" /><category term="Computer architecture" /><category term="Endianness" /><category term="Tray icon" /><category term="Unicode" /><category term="MFC" /><category term="UAC" /><category term="STL" /><category term="Eclipse" /><category term="PyInstaller" /><category term="NSIS" /><category term="Memory dump" /><category term="DOS" /><title>My public notepad</title><subtitle type="html" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://bojan-komazec.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://bojan-komazec.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Bojan Komazec</name><uri>https://profiles.google.com/117174187628268281803</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>61</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/MyPublicNotepad" /><feedburner:info uri="mypublicnotepad" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;D0YFRns7fCp7ImA9WhRUGUk.&quot;"><id>tag:blogger.com,1999:blog-4912226416400969049.post-4222561953327131509</id><published>2012-01-30T17:20:00.000Z</published><updated>2012-01-30T17:38:37.504Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-30T17:38:37.504Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="multithreading" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><title>Thread and process synchronisation with mutex</title><content type="html">In my &lt;a href="http://bojan-komazec.blogspot.com/2012/01/thread-and-process-synchronisation-with.html"&gt;previous article&lt;/a&gt; I described how to use semaphore in order to synchronise threads or processes. Mutex is a semaphore specialisation and can be used in the special case - when only one thread (or process) is allowed to access shared resource.&lt;br /&gt;
&lt;br /&gt;
Mutex is a synchronisation object that controls resource access (critical section execution) by maintaining the knowledge of its current &lt;i&gt;owner&lt;/i&gt; (accessor - thread or process). Mutex strictly limits access to a single accessor at a time.&lt;br /&gt;
&lt;br /&gt;
Ownership over the mutex is controlled with following operations:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;b&gt;acquire()&lt;/b&gt; (or &lt;b&gt;lock()&lt;/b&gt;) - passes the ownership of the mutex to the calling thread&lt;/li&gt;
&lt;li&gt;&lt;b&gt;release()&lt;/b&gt; (or &lt;b&gt;unlock()&lt;/b&gt;) - calling thread gives up its ownership of mutex. Only thread that acquired the mutex can release it&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
Mutex has two states:&lt;br /&gt;
&lt;ul style="text-align: left;"&gt;&lt;li&gt;&lt;b&gt;signalled&lt;/b&gt; - when no thread owns it; &lt;b&gt;acquire()&lt;/b&gt;&amp;nbsp;does not block&lt;/li&gt;
&lt;li&gt;&lt;b&gt;non-signalled&lt;/b&gt; - when owned by some thread; &lt;b&gt;acquire()&lt;/b&gt; in other thread blocks till mutex gets signalled&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
When Thread1 acquires ownership of mutex, it has a exclusive right to access the shared resource (to execute the code in the critical section). Once it's finished, it needs to release mutex so another thread can acquire ownership and access the resource. If thread does not release the mutex, other threads cannot acquire it and application is in a deadlock. It is therefore very important to make sure that mutex is released under any condition, no matter of the outcome of the code in the critical section! RAII-compliant design can prevent program's execution to leave critical section's scope without releasing the mutex.&lt;br /&gt;
&lt;br /&gt;
Semaphore behaves like shared mutex with a count controlled by multiple threads that are allowed to access shared resource. Mutex is stricter, only thread that owns it has the power to release it, and only that thread can access shared resource.&lt;br /&gt;
&lt;br /&gt;
The following example shows how to use mutex in order to synchronise processes that write into the shared file (problem described in &lt;a href="http://bojan-komazec.blogspot.com/2012/01/thread-and-process-synchronisation-with.html"&gt;this article&lt;/a&gt;):&lt;br /&gt;
&lt;br /&gt;
main.cpp:&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#include &lt;string&gt;
#include &lt;iostream&gt;
#include &lt;fstream&gt;
#include &lt;Windows.h&gt;

using std::string;
using std::cout;
using std::endl;
using std::ofstream;

class CScopedMutex
{
 HANDLE m_hMutex;

public:
 CScopedMutex(BOOL bInitialOwner, LPCTSTR lpName) : m_hMutex(0)
 { 
  // if bInitialOwner == TRUE, this thread obtains ownership of a mutex
  m_hMutex = CreateMutex(0, bInitialOwner, lpName);

  DWORD dwErrorCode = GetLastError();

  if(m_hMutex)
  {
   if(dwErrorCode == ERROR_ALREADY_EXISTS)
   {
    OutputDebugString("Mutex opened (already created)\n");
   }
   else
   {
    OutputDebugString("Mutex created\n");
   }   
  }
  else
  {   
   OutputDebugString("ERROR: CreateMutex() failed\n");   
   throw 1;
  }
 }

 ~CScopedMutex()
 {
  if(m_hMutex)
  {
   CloseHandle(m_hMutex);
  }
 }

 // obtains ownership of a mutex when completes
 void Acquire()
 {
  if(WAIT_OBJECT_0 == WaitForSingleObject(m_hMutex, INFINITE))
  {
   OutputDebugString("Mutex acquired\n");
  }
 }

 // releases ownership of the mutex (so that another thread can acquire ownership)
 void Release()
 {
  // The ReleaseMutex function fails if the calling thread does not own the mutex object
  if(!ReleaseMutex(m_hMutex))
  {   
   OutputDebugString("ERROR: ReleaseMutex() failed\n");
  }
 }
};

int main(int argc, char* argv[])
{ 
 if(argc != 2)
 {
  cout &lt;&lt; "ERROR: Application started with wrong number of parameters" &lt;&lt; endl;
  return 1;
 }

 string strLogInsertStr(argv[1]);
 std::string strFilePath("c:\\test\\test.log");
 ofstream logFile(strFilePath.c_str(), std::ios::app);

 CScopedMutex mutex(FALSE, "MUTEX_FILE_GUARD");

 for(int n = 1; n &lt;= 1000; n++)
 {  
  DWORD dwPID = GetCurrentProcessId();
  mutex.Acquire();
  logFile &lt;&lt; "[PID = " &lt;&lt; dwPID &lt;&lt; "] Iteration # " &lt;&lt; n &lt;&lt; " " &lt;&lt; strLogInsertStr &lt;&lt; endl;
  mutex.Release();

 }

 return 0;
}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
Links and References:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms684266(v=vs.85).aspx"&gt;Mutex Objects (MSDN)&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms686927(v=vs.85).aspx"&gt;Using Mutex Objects (MSDN)&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/Mutex"&gt;Mutual exclusion (Wikipedia)&lt;/a&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4912226416400969049-4222561953327131509?l=bojan-komazec.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/S6MFr-trIx4BPK6cjvkOmyjMY4A/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/S6MFr-trIx4BPK6cjvkOmyjMY4A/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/S6MFr-trIx4BPK6cjvkOmyjMY4A/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/S6MFr-trIx4BPK6cjvkOmyjMY4A/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/MyPublicNotepad/~4/CtOedylIB-U" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://bojan-komazec.blogspot.com/feeds/4222561953327131509/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4912226416400969049&amp;postID=4222561953327131509" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/4222561953327131509?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/4222561953327131509?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyPublicNotepad/~3/CtOedylIB-U/thread-and-process-synchronisation-with_30.html" title="Thread and process synchronisation with mutex" /><author><name>Bojan Komazec</name><uri>https://profiles.google.com/117174187628268281803</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://bojan-komazec.blogspot.com/2012/01/thread-and-process-synchronisation-with_30.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0ENRn84eyp7ImA9WhRUGUk.&quot;"><id>tag:blogger.com,1999:blog-4912226416400969049.post-7709037732908517240</id><published>2012-01-30T14:25:00.000Z</published><updated>2012-01-30T17:48:17.133Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-30T17:48:17.133Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="logging" /><category scheme="http://www.blogger.com/atom/ns#" term="Windows" /><category scheme="http://www.blogger.com/atom/ns#" term="STL" /><category scheme="http://www.blogger.com/atom/ns#" term="multithreading" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><title>Thread and process synchronisation with semaphores</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Semaphore is a synchronisation object that controls resource access (critical section execution) by maintaining the number (count, &lt;b&gt;n&lt;/b&gt;) of accessors (threads or processes) (still) allowed to access the resource. While mutex strictly limits access to a single accessor at a time, semaphore allows up to &lt;b&gt;N&lt;/b&gt; (&lt;b&gt;N &amp;gt; 0&lt;/b&gt;) parallel accessors. &lt;b&gt;N&lt;/b&gt; is defined when semaphore is being created and it represents maximum possible value of the semaphore count. &lt;br /&gt;
&lt;br /&gt;
Semaphore count is changed through following operations:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;b&gt;wait()&lt;/b&gt;&amp;nbsp;- which, on return, &amp;nbsp;&lt;u&gt;decreases&lt;/u&gt;&amp;nbsp;count on successful return (minimum is &lt;b&gt;0&lt;/b&gt;)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;release()&lt;/b&gt;&amp;nbsp;- which&amp;nbsp;&lt;u&gt;increases&lt;/u&gt;&amp;nbsp;count (maximum is &lt;b&gt;N&lt;/b&gt;)&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
Semaphore has two states:&lt;br /&gt;
&lt;ul style="text-align: left;"&gt;&lt;li&gt;&lt;b&gt;signalled &lt;/b&gt;- when &lt;b&gt;0 &amp;lt; n &amp;lt;= N&lt;/b&gt;; &lt;b&gt;wait()&lt;/b&gt;&amp;nbsp;does not block&lt;/li&gt;
&lt;li&gt;&lt;b&gt;non-signalled&lt;/b&gt; - when &lt;b&gt;n == 0&lt;/b&gt;; &lt;b&gt;wait()&lt;/b&gt; blocks till semaphore gets signalled (or returns on expired timeout)&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
There are two types of semaphores:&lt;br /&gt;
&lt;ul style="text-align: left;"&gt;&lt;li&gt;&lt;b&gt;counting&lt;/b&gt; - based on the count &lt;b&gt;0 &lt;= n &lt;= N&lt;/b&gt; where &lt;b&gt;N &gt; 1&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;binary&lt;/b&gt; - (specialisation of counting) where &lt;b&gt;N == 1&lt;/b&gt;; when in signalled state we say it is &lt;b&gt;unlocked&lt;/b&gt;; when in non-signalled state we say it is &lt;b&gt;locked&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
Semaphores are &lt;i&gt;signalling&lt;/i&gt; accessors the right of way - just as traffic semaphores, but unlike them, accessors themselves are controlling when the light for others will become green - through &lt;b&gt;wait()&lt;/b&gt; and &lt;b&gt;release()&lt;/b&gt; operations. Accessors are &lt;b&gt;wait()&lt;/b&gt;-ing for a semaphore. If semaphore is signalled (&lt;b&gt;n &amp;gt; 0&lt;/b&gt;), &lt;b&gt;wait()&lt;/b&gt; returns immediately, decreasing semaphore count. When accessor (this one or any other) is finished with the shared resource it calls &lt;b&gt;release()&lt;/b&gt; on the semaphore, increasing its count. Accessor will block on &lt;b&gt;wait()&lt;/b&gt;-ing if semaphore is non-signalled (when maximum allowed number of accessors are sharing the resource). As soon as some accessor finishes the work and &lt;b&gt;releases&lt;/b&gt; the semaphore, accessor's &lt;b&gt;wait()&lt;/b&gt; will unblock and it will be allowed to access the resource.&lt;br /&gt;
&lt;br /&gt;
Obviously, if &lt;b&gt;N&lt;/b&gt; is set to &lt;b&gt;1&lt;/b&gt;, semaphore (called &lt;i&gt;binary semaphore&lt;/i&gt; in this case) logically behaves like a mutex, allowing only one accessor at a time. There is a difference between two of them though: only accessor that locked the mutex can unlock it (mutex is &lt;i&gt;owned&lt;/i&gt; by the accessor), but any accessor can release semaphore. &lt;br /&gt;
&lt;br /&gt;
Majority of semaphore examples on the internet are focused on &lt;a href="http://en.wikipedia.org/wiki/Producer-consumer_problem"&gt;consumer-producer problem&lt;/a&gt;. I wanted to show use of semaphore on the example of traffic control - something that resembles the real semaphore. So, let's say we have three single-lane, one way roads joining just before a bridge which is one way but has two lanes. To reduce congestion on the bridge, traffic from only two access roads is allowed at a time. There is a semaphore with the red and green light by the each road and once it turns green, it remains in that state for some time period &lt;b&gt;T&lt;/b&gt;. First two opened roads get green light first. As soon as the timeout expires for one of those roads and semaphore shows red, semaphore will show green for traffic that has been waiting at the third road. &lt;br /&gt;
&lt;br /&gt;
&lt;div style="text-align: center;"&gt;&lt;a href="http://www.flickr.com/photos/25233492@N05/6771817665/" title="Semaphore-example by Bojan Komazec, on Flickr"&gt;&lt;img src="http://farm8.staticflickr.com/7011/6771817665_906b92f21d.jpg" width="409" height="292" alt="Semaphore-example"&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
We can think of roads (traffic on them) as &lt;i&gt;accessors&lt;/i&gt; and the bridge as a &lt;i&gt;resource&lt;/i&gt;: two roads can lead traffic to the bridge at the same time (two accessors are allowed to access shared resource). Obviously, we will set the maximum value for the semaphore count to &lt;b&gt;2&lt;/b&gt; in our model. Thread will &lt;b&gt;wait()&lt;/b&gt; as long as count is &lt;b&gt;0&lt;/b&gt; but as soon as it gets increased to &lt;b&gt;1&lt;/b&gt;, &lt;b&gt;wait()&lt;/b&gt; returns (decreasing count to &lt;b&gt;0&lt;/b&gt; again). &lt;br /&gt;
&lt;br /&gt;
This example aims to show how semaphore limits parallel access to the shared resource and how accessors (threads in this case) themselves control semaphore by &lt;b&gt;wait()&lt;/b&gt;-ing for the semaphore and &lt;b&gt;release()&lt;/b&gt;-ing it.&lt;br /&gt;
&lt;br /&gt;
To stop threads I tend to use &lt;i&gt;event&lt;/i&gt; object - not a flag (volatile &lt;i&gt;bool variable&lt;/i&gt;). They are thread-safe and thread callbacks don't need to return with delay of one additional wait() cycle in the case when termination has been requested.&lt;br /&gt;
&lt;br /&gt;
I wrapped event and semaphore objects (handles) into RAII-compliant classes - &lt;b&gt;CScopedEvent&lt;/b&gt; and &lt;b&gt;CScopedSemaphore&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
main.cpp:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#include &lt;Windows.h&gt;
#include &lt;iostream&gt;
#include &lt;assert.h&gt;

// cout is not thread safe! (but I'll ignore it here)
using std::cout;
using std::endl;

class CScopedEvent
{
 HANDLE m_hEvent;

public:
 CScopedEvent() : m_hEvent(0){}

 CScopedEvent(BOOL bManualReset, BOOL bInitialState, LPCTSTR lpName) : m_hEvent(0)
 {  
  m_hEvent = CreateEvent(0, bManualReset, bInitialState, lpName);

  DWORD dwErrorCode = GetLastError();

  if(m_hEvent)
  {
   if(dwErrorCode == ERROR_ALREADY_EXISTS)
   {
    OutputDebugString("Event opened (already created)\n");
   }
   else
   {
    OutputDebugString("Event created\n");
   }   
  }
  else
  {   
   OutputDebugString("ERROR: CreateEvent() failed\n");   
   throw 1;
  }
 } 

 ~CScopedEvent()
 {
  if(m_hEvent)
  {
   CloseHandle(m_hEvent);
   m_hEvent = 0;
  }
 }

 // semaphore count is decremented when wait completes
 void Wait()
 {
  if(WAIT_OBJECT_0 == WaitForSingleObject(m_hEvent, INFINITE))
  {
   OutputDebugString("Event signalled\n");
  }
 }

 void Set(BOOL bSet)
 {
  if(bSet)
  {   
   if(!SetEvent(m_hEvent))
   {    
    OutputDebugString("ERROR: SetEvent() failed\n");
   }
  }
  else
  {   
   if(!ResetEvent(m_hEvent))
   {    
    OutputDebugString("ERROR: ResetEvent() failed\n");
   }
  }
 }

 // if the client wants to wait for multiple objects, one of which is this handle
 HANDLE GetNativeHandle() const
 {
  return m_hEvent;
 }
};

class CScopedSemaphore
{
 HANDLE m_hSemaphore;

public:
 CScopedSemaphore() : m_hSemaphore(0){}

 CScopedSemaphore(LONG lInitialCount, LONG lMaximumCount, LPCTSTR lpName) : m_hSemaphore(0)
 {  
  m_hSemaphore = CreateSemaphore(0, lInitialCount, lMaximumCount, lpName);

  DWORD dwErrorCode = GetLastError();

  if(m_hSemaphore)
  {
   if(dwErrorCode == ERROR_ALREADY_EXISTS)
   {
    OutputDebugString("Semaphore opened (already created)\n");
   }
   else
   {
    OutputDebugString("Semaphore created\n");
   }   
  }
  else
  {  
   OutputDebugString("ERROR: CreateSemaphore() failed\n");   
   throw 1;
  }
 } 

 ~CScopedSemaphore()
 {
  if(m_hSemaphore)
  {
   CloseHandle(m_hSemaphore);
   m_hSemaphore = 0;
  }
 }

 // semaphore count is decremented when wait completes
 void Wait()
 {
  if(WAIT_OBJECT_0 == WaitForSingleObject(m_hSemaphore, INFINITE))
  {
   OutputDebugString("Semaphore signalled\n");
  }
 }

 // semaphore count is incremented when ReleaseSemaphore completes
 // Release()
 void Signal()
 {
  // increase count by 1
  if(!ReleaseSemaphore(m_hSemaphore, 1, 0))
  {   
   OutputDebugString("ERROR: ReleaseSemaphore() failed\n");
  }
 }

 // if the client wants to wait for multiple objects, one of which is this handle
 HANDLE GetNativeHandle() const
 {
  return m_hSemaphore;
 }
};

class CRoad
{
 int m_nID;
 HANDLE m_hThread;

 // roads are sharing same syncronisation object - semaphore
 CScopedSemaphore&amp; m_semaphore;

 CScopedEvent m_eventCloseRoad;

 // seconds
 static const int SEMAPHORE_INTERVAL = 10;

 static int m_nRoadsGeneratingTraffic;
 
public:
 CRoad(int nID, CScopedSemaphore&amp; semaphore) : 
   m_nID(nID),
   m_semaphore(semaphore),
   m_eventCloseRoad(FALSE, FALSE, "")
 {  
  m_hThread = CreateThread(0, 0, &amp;CRoad::OpenRoad, this, 0, 0);

  if(!m_hThread)
   throw 1;
 } 
 
 static DWORD WINAPI OpenRoad(void* pArg)
 {
  assert(pArg);
  CRoad* pRoad = reinterpret_cast&lt;CRoad*&gt;(pArg);
  cout &lt;&lt; "Road " &lt;&lt; pRoad-&gt;m_nID &lt;&lt; " opened" &lt;&lt; endl;
  
  HANDLE waitHandles[2] = {pRoad-&gt;m_eventCloseRoad.GetNativeHandle(), pRoad-&gt;m_semaphore.GetNativeHandle()};
  bool bKeepRunning = true;

  while(bKeepRunning)
  {   
   cout &lt;&lt; m_nRoadsGeneratingTraffic &lt;&lt; " road(s) is(are) generating traffic..." &lt;&lt; endl;
   DWORD dwRetVal = WaitForMultipleObjects(2, waitHandles, FALSE, INFINITE);

   switch(dwRetVal)
   {
   case WAIT_OBJECT_0:
    {
     cout &lt;&lt; "Road " &lt;&lt; pRoad-&gt;m_nID &lt;&lt; " got request to get closed" &lt;&lt; endl;
     bKeepRunning = false;
     break;
    }
   case WAIT_OBJECT_0 + 1:
    {
     cout &lt;&lt; "Road " &lt;&lt; pRoad-&gt;m_nID &lt;&lt; " got green light for the next " &lt;&lt; pRoad-&gt;SEMAPHORE_INTERVAL &lt;&lt; " seconds. Generating traffic..." &lt;&lt; endl;

     m_nRoadsGeneratingTraffic++;
     cout &lt;&lt; m_nRoadsGeneratingTraffic &lt;&lt; " road(s) is(are) generating traffic..." &lt;&lt; endl;

     // it is now directing the traffic to the bridge (shared resource)
     Sleep(SEMAPHORE_INTERVAL * 1000); 

     cout &lt;&lt; "\nRoad " &lt;&lt; pRoad-&gt;m_nID &lt;&lt; " got red light. Waiting for a green light..." &lt;&lt; endl;
     m_nRoadsGeneratingTraffic--;
     
     pRoad-&gt;m_semaphore.Signal();
     break;
    }
   }   
  }  

  return 0;
 }

 ~CRoad()
 {
  m_eventCloseRoad.Set(true);

  cout &lt;&lt; "Closing road " &lt;&lt; m_nID &lt;&lt; " ..." &lt;&lt; endl;

  WaitForSingleObject(m_hThread, INFINITE);

  cout &lt;&lt; "Road " &lt;&lt; m_nID &lt;&lt; " closed" &lt;&lt; endl;
 }
};

int CRoad::m_nRoadsGeneratingTraffic = 0;

int main()
{
 // semaphore name could be an empty string as semaphore is used only within this process
 CScopedSemaphore semaphore(2, 2, "BRIDGE_SEMAPHORE");

 CRoad road1(1, semaphore);
 Sleep(1000);

 CRoad road2(2, semaphore);
 Sleep(2000);

 CRoad road3(3, semaphore); 

 // observe traffic for 1 minute
 Sleep(60000); 
  
 return 0;
}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
Output:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="cmd_line"&gt;Road 1 opened&lt;br /&gt;
0 road(s) is(are) generating traffic...&lt;br /&gt;
Road 1 got green light for the next 10 seconds. Generating traffic...&lt;br /&gt;
1 road(s) is(are) generating traffic...&lt;br /&gt;
Road 2 opened&lt;br /&gt;
1 road(s) is(are) generating traffic...&lt;br /&gt;
Road 2 got green light for the next 10 seconds. Generating traffic...&lt;br /&gt;
2 road(s) is(are) generating traffic...&lt;br /&gt;
Road 3 opened&lt;br /&gt;
2 road(s) is(are) generating traffic...&lt;br /&gt;
&lt;br /&gt;
Road 1 got red light. Waiting for a green light...&lt;br /&gt;
1 road(s) is(are) generating traffic...&lt;br /&gt;
Road 3 got green light for the next 10 seconds. Generating traffic...&lt;br /&gt;
2 road(s) is(are) generating traffic...&lt;br /&gt;
&lt;br /&gt;
Road 2 got red light. Waiting for a green light...&lt;br /&gt;
1 road(s) is(are) generating traffic...&lt;br /&gt;
Road 1 got green light for the next 10 seconds. Generating traffic...&lt;br /&gt;
2 road(s) is(are) generating traffic...&lt;br /&gt;
&lt;br /&gt;
Road 3 got red light. Waiting for a green light...&lt;br /&gt;
1 road(s) is(are) generating traffic...&lt;br /&gt;
Road 2 got green light for the next 10 seconds. Generating traffic...&lt;br /&gt;
2 road(s) is(are) generating traffic...&lt;br /&gt;
&lt;br /&gt;
Road 1 got red light. Waiting for a green light...&lt;br /&gt;
1 road(s) is(are) generating traffic...&lt;br /&gt;
Road 3 got green light for the next 10 seconds. Generating traffic...&lt;br /&gt;
2 road(s) is(are) generating traffic...&lt;br /&gt;
&lt;br /&gt;
Road 2 got red light. Waiting for a green light...&lt;br /&gt;
1 road(s) is(are) generating traffic...&lt;br /&gt;
Road 1 got green light for the next 10 seconds. Generating traffic...&lt;br /&gt;
2 road(s) is(are) generating traffic...&lt;br /&gt;
&lt;br /&gt;
Road 3 got red light. Waiting for a green light...&lt;br /&gt;
1 road(s) is(are) generating traffic...&lt;br /&gt;
Road 2 got green light for the next 10 seconds. Generating traffic...&lt;br /&gt;
2 road(s) is(are) generating traffic...&lt;br /&gt;
&lt;br /&gt;
Road 1 got red light. Waiting for a green light...&lt;br /&gt;
Road 3 got green light for the next 10 seconds. Generating traffic...&lt;br /&gt;
1 road(s) is(are) generating traffic...2 road(s) is(are) generating traffic...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Road 2 got red light. Waiting for a green light...&lt;br /&gt;
1 road(s) is(are) generating traffic...&lt;br /&gt;
Road 1 got green light for the next 10 seconds. Generating traffic...&lt;br /&gt;
2 road(s) is(are) generating traffic...&lt;br /&gt;
&lt;br /&gt;
Road 3 got red light. Waiting for a green light...&lt;br /&gt;
1 road(s) is(are) generating traffic...&lt;br /&gt;
Road 2 got green light for the next 10 seconds. Generating traffic...&lt;br /&gt;
2 road(s) is(are) generating traffic...&lt;br /&gt;
&lt;br /&gt;
Road 1 got red light. Waiting for a green light...&lt;br /&gt;
Road 3 got green light for the next 10 seconds. Generating traffic...&lt;br /&gt;
1 road(s) is(are) generating traffic...&lt;br /&gt;
2 road(s) is(are) generating traffic...&lt;br /&gt;
&lt;br /&gt;
Road 2 got red light. Waiting for a green light...&lt;br /&gt;
1 road(s) is(are) generating traffic...&lt;br /&gt;
Road 1 got green light for the next 10 seconds. Generating traffic...&lt;br /&gt;
2 road(s) is(are) generating traffic...&lt;br /&gt;
&lt;br /&gt;
Road 3 got red light. Waiting for a green light...&lt;br /&gt;
1 road(s) is(are) generating traffic...&lt;br /&gt;
Road 2 got green light for the next 10 seconds. Generating traffic...&lt;br /&gt;
2 road(s) is(are) generating traffic...&lt;br /&gt;
Closing road 3 ...&lt;br /&gt;
Road 3 got request to get closed&lt;br /&gt;
Road 3 closed&lt;br /&gt;
Closing road 2 ...&lt;br /&gt;
&lt;br /&gt;
Road 1 got red light. Waiting for a green light...&lt;br /&gt;
1 road(s) is(are) generating traffic...&lt;br /&gt;
Road 1 got green light for the next 10 seconds. Generating traffic...&lt;br /&gt;
2 road(s) is(are) generating traffic...&lt;br /&gt;
&lt;br /&gt;
Road 2 got red light. Waiting for a green light...&lt;br /&gt;
1 road(s) is(are) generating traffic...&lt;br /&gt;
Road 2 got request to get closed&lt;br /&gt;
Road 2 closed&lt;br /&gt;
Closing road 1 ...&lt;br /&gt;
&lt;br /&gt;
Road 1 got red light. Waiting for a green light...&lt;br /&gt;
0 road(s) is(are) generating traffic...&lt;br /&gt;
Road 1 got request to get closed&lt;br /&gt;
Road 1 closed&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
The example above shows how semaphore controls access to the resource by multiple threads. But please note that resource was NOT made thread safe! Semaphore was just allowing up to &lt;b&gt;N&lt;/b&gt; threads (&lt;b&gt;2&lt;/b&gt; in our case) to be active at a time (and generate the traffic towards the bridge). If we wanted to limit the number of vehicles on the bridge and to control traffic lights depending on the current bridge load, we would have had to limit the number of active threads to &lt;b&gt;1&lt;/b&gt;. In that case only one road would have green light at a time. &lt;br /&gt;
&lt;br /&gt;
In the next example I want to show how to synchronise multiple processes in accessing shared resource. Let's say we have an app which writes some log into the file and does it in a loop. The code could look like this:&lt;br /&gt;
&lt;br /&gt;
main.cpp:&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#include &lt;string&gt;
#include &lt;iostream&gt;
#include &lt;fstream&gt;
#include &lt;Windows.h&gt;

using std::string;
using std::cout;
using std::endl;
using std::ofstream;

int main(int argc, char* argv[])
{ 
 if(argc != 2)
 {
  cout &lt;&lt; "ERROR: Application started with wrong number of parameters" &lt;&lt; endl;
  return 1;
 }

 string strLogInsertStr(argv[1]);
 string strFilePath("c:\\test\\test.log");
 ofstream logFile(strFilePath.c_str(), std::ios::app);

 for(int n = 1; n &lt;= 1000; n++)
 {    
  logFile &lt;&lt; "[PID = " &lt;&lt; GetCurrentProcessId() &lt;&lt; "] Iteration # " &lt;&lt; n &lt;&lt; " " &lt;&lt; strLogInsertStr &lt;&lt; endl;
 }

 return 0;
}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
If run with parameter of value e.g. "012345", this app will create text file with the following content:&lt;br /&gt;
&lt;br /&gt;
test.log:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="file_hierarchy"&gt;[PID = 4408] Iteration # 1 012345&lt;br /&gt;
[PID = 4408] Iteration # 2 012345&lt;br /&gt;
[PID = 4408] Iteration # 3 012345&lt;br /&gt;
[PID = 4408] Iteration # 4 012345&lt;br /&gt;
...&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
If we run simultaneously two or more instances of this process, they will all write into the same file, increasing its size with each write operation. Manipulator &lt;b&gt;endl&lt;/b&gt; inserts new line character (&lt;b&gt;'\n'&lt;/b&gt;) at the end of the line and &lt;i&gt;flushes&lt;/i&gt; the buffer to the disk. Obviously, before writing to the disk, our file stream object needs to know the current size of the file in order to move write pointer to the file end. If Process2 appends a new line to the file after Process1 reads file size but before Process1 writes into it, Process2 will increase file size but Process1 will know only about the previous file size and start writing at the position set accordingly, effectively overwriting Process2's last written line!&lt;br /&gt;
&lt;br /&gt;
The following code is the content of the script (DOS batch file) which runs three instances of our application, providing each with different argument:&lt;br /&gt;
&lt;br /&gt;
run_processes.bat:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="cmd_line"&gt;@start Process.exe 012345&lt;br /&gt;
@start Process.exe ABCDEFHIJKLM&lt;br /&gt;
@start Process.exe 987654321&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
Arguments are of different length so we can easily detect the place of the corruption in the output file, like this one:&lt;br /&gt;
&lt;br /&gt;
test.log:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="file_hierarchy"&gt;...&lt;br /&gt;
[PID = 8280] Iteration # 214 ABCDEFHIJKLM&lt;br /&gt;
[PID = 8120] Iteration # 208 987654321&lt;br /&gt;
M&lt;br /&gt;
[PID = 8280] Iteration # 216 ABCDEFHIJKLM&lt;br /&gt;
...&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
What happened here? First of all, we need to know that on Windows, &lt;b&gt;\n&lt;/b&gt; read from stream buffer is expanded to &lt;b&gt;\r\n&lt;/b&gt; (&lt;b&gt;CR-LF&lt;/b&gt;) before writing it to the file on disk. Process 8120 has updated its knowledge of file size but before it wrote iteration #208 log, process 8280 had written its log for iteration #215 so basically we had this:&lt;br /&gt;
&lt;br /&gt;
test.log (showing hidden CR-LF characters):&lt;br /&gt;
&lt;br /&gt;
&lt;div class="file_hierarchy"&gt;...&lt;br /&gt;
[PID = 8280] Iteration # 214 ABCDEFHIJKLM\r\n&lt;br /&gt;
[PID = 8280] Iteration # 215 ABCDEFHIJKLM\r\n&lt;br /&gt;
...&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
Then process 8120 wrote its #208 log, but effectively overwriting 8280's #215, after what 8280 wrote its log #216:&lt;br /&gt;
&lt;br /&gt;
test.log (showing hidden CR-LF characters):&lt;br /&gt;
&lt;br /&gt;
&lt;div class="file_hierarchy"&gt;...&lt;br /&gt;
[PID = 8280] Iteration # 214 ABCDEFHIJKLM\r\n&lt;br /&gt;
[PID = 8120] Iteration # 208 987654321\r\nM\r\n&lt;br /&gt;
[PID = 8280] Iteration # 216 ABCDEFHIJKLM\r\n&lt;br /&gt;
...&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
Obviosuly, we need to protect file so only one process is accessing it at a time. We can do that with &lt;i&gt;semaphore&lt;/i&gt; or &lt;i&gt;mutex&lt;/i&gt; which are shared between multiple processes (and therefore must be &lt;i&gt;named&lt;/i&gt;).&lt;br /&gt;
&lt;br /&gt;
In this article I will show how to achieve it with semaphore:&lt;br /&gt;
&lt;br /&gt;
main.cpp:&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#include &lt;string&gt;
#include &lt;iostream&gt;
#include &lt;fstream&gt;
#include &lt;Windows.h&gt;

using std::string;
using std::cout;
using std::endl;
using std::ofstream;

class CScopedSemaphore
{
 HANDLE m_hSemaphore;

public:
 CScopedSemaphore(LONG lInitialCount, LONG lMaximumCount, LPCTSTR lpName) : m_hSemaphore(0)
 {  
  m_hSemaphore = CreateSemaphore(0, lInitialCount, lMaximumCount, lpName);

  DWORD dwErrorCode = GetLastError();

  if(m_hSemaphore)
  {
   if(dwErrorCode == ERROR_ALREADY_EXISTS)
   {
    OutputDebugString("Semaphore opened (already created)\n");
   }
   else
   {
    OutputDebugString("Semaphore created\n");
   }   
  }
  else
  {   
   OutputDebugString("ERROR: CreateSemaphore() failed\n");   
   throw 1;
  }
 }

 ~CScopedSemaphore()
 {
  if(m_hSemaphore)
  {
   CloseHandle(m_hSemaphore);
  }
 }

 // semaphore count is decremented when wait completes
 void Wait()
 {
  if(WAIT_OBJECT_0 == WaitForSingleObject(m_hSemaphore, INFINITE))
  {
   OutputDebugString("Semaphore signalled\n");
  }
 }

 // semaphore count is incremented when ReleaseSemaphore completes
 // Release()
 void Signal()
 {
  // increase count by 1
  if(!ReleaseSemaphore(m_hSemaphore, 1, 0))
  {   
   OutputDebugString("ERROR: ReleaseSemaphore() failed\n");
  }
 }
};

int main(int argc, char* argv[])
{ 
 if(argc != 2)
 {
  cout &lt;&lt; "ERROR: Application started with wrong number of parameters" &lt;&lt; endl;
  return 1;
 }

 string strLogInsertStr(argv[1]);
 string strFilePath("c:\\test\\test.log");
 ofstream logFile(strFilePath.c_str(), std::ios::app);

 CScopedSemaphore semaphore(1, 1, "SEMAPHORE_FILE_GUARD");

 for(int n = 1; n &lt;= 1000; n++)
 {    
  semaphore.Wait();
  logFile &lt;&lt; "[PID = " &lt;&lt; GetCurrentProcessId() &lt;&lt; "] Iteration # " &lt;&lt; n &lt;&lt; " " &lt;&lt; strLogInsertStr &lt;&lt; endl;
  semaphore.Signal();

 }
 return 0;
}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
All processes are competing to get semaphore signal. First process whose &lt;b&gt;wait()&lt;/b&gt; returns (decreasing semaphore count by &lt;b&gt;1&lt;/b&gt; - possibly to minimal value of &lt;b&gt;0&lt;/b&gt; in which case all other processes block on their &lt;b&gt;wait()&lt;/b&gt;) gets a exclusive access to a file and updates its content after which it releases semaphore (increasing its count to &lt;b&gt;1&lt;/b&gt; again). All processes are competing again and the one whose &lt;b&gt;wait()&lt;/b&gt; returns first gets its slot of exclusive access. There is no corruption in the file any more:&lt;br /&gt;
&lt;br /&gt;
test.log:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="file_hierarchy"&gt;...&lt;br /&gt;
[PID = 6036] Iteration # 213 987654321&lt;br /&gt;
[PID = 10940] Iteration # 213 012345&lt;br /&gt;
[PID = 11644] Iteration # 213 ABCDEFHIJKLM&lt;br /&gt;
[PID = 6036] Iteration # 214 987654321&lt;br /&gt;
[PID = 10940] Iteration # 214 012345&lt;br /&gt;
[PID = 11644] Iteration # 214 ABCDEFHIJKLM&lt;br /&gt;
[PID = 6036] Iteration # 215 987654321&lt;br /&gt;
[PID = 10940] Iteration # 215 012345&lt;br /&gt;
[PID = 11644] Iteration # 215 ABCDEFHIJKLM&lt;br /&gt;
...&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
Note: Although this example uses &lt;i&gt;semaphore&lt;/i&gt; for process synchronisation, &lt;i&gt;mutex&lt;/i&gt; is here more natural solution - we don't want to limit number of accessors to several (&lt;b&gt;N&lt;/b&gt;) but only to &lt;b&gt;1&lt;/b&gt;. Only process that locks the mutex can unlock it and with &lt;i&gt;binary semaphore&lt;/i&gt; we are just emulating this behaviour.  &lt;br /&gt;
&lt;br /&gt;
Links and References:&lt;br /&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/ms685129(v=vs.85).aspx"&gt;Semaphore Objects (MSDN)&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/ms686946(v=vs.85).aspx"&gt;Using Semaphore Objects (MSDN)&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/Semaphore_(programming)"&gt;Semaphore (Wikipedia)&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.installsetupconfig.com/win32programming/threadprocesssynchronizationapis11_44.html"&gt;Windows Thread Synchronization - Synchronization Using Semaphores&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.flounder.com/semaphores.htm"&gt;Joseph M. Newcomer: Semaphores&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://sendreceivereply.wordpress.com/2007/04/10/mutex-or-semaphore-for-performance/"&gt;Mutex or Semaphore for Performance?&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.geeksforgeeks.org/archives/9102"&gt;Mutex vs Semaphore&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;a href="http://blog.feabhas.com/2009/09/mutex-vs-semaphores-%E2%80%93-part-1-semaphores/"&gt;Mutex vs Semaphores&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://stackoverflow.com/questions/62814/difference-between-binary-semaphore-and-mutex"&gt;Difference between binary semaphore and mutex&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4912226416400969049-7709037732908517240?l=bojan-komazec.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/V6dTfMrAxg2WaAGSjD7Wp-hh5ew/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/V6dTfMrAxg2WaAGSjD7Wp-hh5ew/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/V6dTfMrAxg2WaAGSjD7Wp-hh5ew/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/V6dTfMrAxg2WaAGSjD7Wp-hh5ew/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/MyPublicNotepad/~4/xHjJu58Lbyw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://bojan-komazec.blogspot.com/feeds/7709037732908517240/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4912226416400969049&amp;postID=7709037732908517240" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/7709037732908517240?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/7709037732908517240?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyPublicNotepad/~3/xHjJu58Lbyw/thread-and-process-synchronisation-with.html" title="Thread and process synchronisation with semaphores" /><author><name>Bojan Komazec</name><uri>https://profiles.google.com/117174187628268281803</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://bojan-komazec.blogspot.com/2012/01/thread-and-process-synchronisation-with.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEcNRH06fyp7ImA9WhRVGUU.&quot;"><id>tag:blogger.com,1999:blog-4912226416400969049.post-6263918439954648098</id><published>2012-01-19T15:14:00.000Z</published><updated>2012-01-19T15:14:55.317Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-19T15:14:55.317Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="UML" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><title>UML Class Diagrams and Class Relationships</title><content type="html">UML Class Diagrams display relationships between classes in a given model. Here is a list of various types of class relationships and statements that can describe them:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;b&gt; generalization&lt;/b&gt; ("A is &lt;i&gt;a kind of&lt;/i&gt; B")&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt; realization&lt;/b&gt; ("A&lt;i&gt; implements&lt;/i&gt; B")&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt; dependency&lt;/b&gt; ("A &lt;i&gt;uses&lt;/i&gt; B and &lt;i&gt;forgets&lt;/i&gt; about it", "A can send message to B")&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt; association&lt;/b&gt; ("A &lt;i&gt;uses&lt;/i&gt; B and &lt;i&gt;keeps&lt;/i&gt; it", "A &lt;i&gt;has&lt;/i&gt; B")&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt; aggregation&lt;/b&gt; ("B can be a &lt;i&gt;part&lt;/i&gt; of A (&lt;i&gt;whole&lt;/i&gt;)", "B can outlive A", "B can be &lt;i&gt;shared&lt;/i&gt; between many As")&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt; composition&lt;/b&gt; ("B is a &lt;i&gt;part&lt;/i&gt; of A (&lt;i&gt;whole&lt;/i&gt;)", "A &lt;i&gt;owns&lt;/i&gt; B", "B cannot outlive A", "B belongs only to one A")&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;It is usually easy to distinguish generalization from realization, aggregation from composition but the border line between  dependency, association and aggregation is a bit blurry. All these relationships are actually some kinds of associations which differ in subtle details and which can be redefined depending on the context.&amp;nbsp;Different books and articles on UML&amp;nbsp;sometimes&amp;nbsp;define these relationships in a very different way ("dependency is a type of association" vs. "association is a type of dependency", "aggregation is meaningless"...) and some are even advising (with a reason!) to give up differentiating them:&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;"Rule 145. Don't Worry About the Diamonds: When you are deciding whether to use aggregation or composition over association, Craig Larman (2002) says it best: "If in doubt, leave it out." The reality is that many modelers will agonize over when to use aggregation when the reality is that there is very little difference between association, aggregation, and composition at the coding level."&lt;/i&gt; [12]&lt;br /&gt;
&lt;br /&gt;
I tried to find an algorithm which goes through a set of questions (based on aforementioned statements) about the relationship between class A and class B and which at the end yields the name of that relationship.&lt;br /&gt;
&lt;br /&gt;
Here is the algorithm I came up with:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.flickr.com/photos/25233492@N05/6725556373/" title="ClassRelationshipsAlgorithm by Bojan Komazec, on Flickr"&gt;&lt;img src="http://farm8.staticflickr.com/7165/6725556373_a77cdb0242_b.jpg" width="778" height="1024" alt="ClassRelationshipsAlgorithm"&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Here are some descriptions of class relationships I found in various UML-related books:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;b&gt;Dependency&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;The weakest relationship between classes is a dependency relationship. Dependency between classes means that one class uses, or has knowledge of, another class. It is typically a transient relationship, meaning a dependent class briefly interacts with the target class but typically doesn't retain a relationship with it for any real length of time. Dependencies are typically read as "...uses a...". For example, if you have a class named Window that sends out a class named WindowClosingEvent when it is about to be closed, you would say "Window uses a WindowClosingEvent." You show a dependency between classes using a dashed line with an arrow pointing from the dependent class to the class that is used.&lt;/i&gt; [1]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;A dependency exists between two elements if changes to the definition of one element (the supplier) may cause changes to the other (the client). With classes, dependencies exist for various reasons: One class sends a message to another; one class has another as part of its data; one class mentions another as a parameter to an operation. If a class changes its interface, any message sent to that class may no longer be valid. (...) The UML allows you to depict dependencies between all sorts of elements. You use dependencies whenever you want to show how changes in one element might alter other elements.&lt;/i&gt; [2]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;(...) Your general rule should be to minimize dependencies &lt;/i&gt;[2]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;(... ) The most common case I use for dependencies with classes is when illustrating a transient relationship, such as when one object is passed to another as a parameter. &lt;/i&gt;[2]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;...one class uses another. This is called a dependency. The most common usage of a dependency is to show that the signature of one class' operation uses another class. &lt;/i&gt;[3]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Dependency—the relationship between a component and an interface through which it accesses another component. (...) dependency is visualized as a dashed line with an arrowhead.&lt;/i&gt; [3]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;You model interaction through an interface as a dependency.&lt;/i&gt; [3]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Sometimes the relationship between a two classes is very weak. They are not implemented with member variables at all. Rather they might be implemented as member function arguments. (...) This is the dependency relationship. In Booch94 this was called a ‘using’ relationship. This relationship simply means that A somehow depends upon B. In C++ this almost always results in a #include. &lt;/i&gt;[5]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;A dependency is a "using" relationship within which a change in one thing (such as a class) may affect another thing (for instance, another class). The dependent element is called the client or source; the independent element is called the supplier or target. A dependency involving two classes appears as a dashed line with a  feathered arrow pointing at the supplier. &lt;/i&gt;[8]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;The UML includes a general dependency relationship, which indicates that one element (of any kind, including classes, use cases, and so on) has knowledge of another element. It is illustrated with a dashed arrow line. In class diagrams the dependency relationship is useful to depict non-attribute visibility between classes; in other words, parameter, global, or locally declared visibility. By contrast, plain attribute visibility is shown with a regular association line and a navigability arrow. For example, the Register software object receives a return object of type ProductSpecification from the specification message it sent to a ProductCatalog. Thus Register has a short-term locally declared visibility to ProductSpecifications. And Sale receives a ProductSpecification as a parameter in the makeLineItem message; it has parameter visibility to one. These non-attribute visibilities may be illustrated with the dashed arrow line indicating a dependency relationship. &lt;/i&gt;[9]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Dependency relationships are indicating non-attribute visibility. &lt;/i&gt; [9]&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;b&gt;Association&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Associations are stronger than dependencies and typically indicate that one class retains a relationship to another class over an extended period of time. The lifelines of two objects linked by associations are probably not tied together (meaning one can be destroyed without necessarily destroying the other). Associations are typically read as "...has a...". For example, if you have a class named Window that has a reference to the current mouse cursor, you would say "Window has a Cursor". Note that there is a fine line between "...has a..." and "...owns a..." (see "Aggregation" later in this section). In this case, Window doesn't own the Cursor; Cursor is shared between all applications in the system. However, Window has a reference to it so that the Window can hide it, change its shape, etc. You show an association using a solid line between the classes participating in the relationship.&lt;/i&gt;[1]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;The other way to notate a property is as an association. Much of the same information that you can show on an attribute appears on an association.&amp;nbsp;&lt;/i&gt;[2]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;An association is a solid line between two classes, directed from the source class to the target class. The name of the property goes at the target end of the association, together with its multiplicity. The target end of the association links to the class that is the type of the property. &lt;/i&gt;[2]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;As an alternative to labeling an association by a property, many people, particularly if they have a data-modeling background, like to label an association by using a verb phrase so that the relationship can be used in a sentence. This is legal and you can add an arrow to the association to avoid ambiguity. Most object modelers prefer to use a property name, as that corresponds better to responsibilities and operations. &lt;/i&gt;[2]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;(...) Because you don't need an association to a class to send a message to it, you may also need to add a dependency arrow to show messages between classes that aren't associated. &lt;/i&gt;[2]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;When classes are connected together conceptually, that connection is called an association. &lt;/i&gt;[3] &lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;When one class associates with another, each one usually plays a role within that association. You can show each class’s role by writing it near the line next to the class. In the association between a player and a team, if the team is professional, it’s an employer and the player is an employee&lt;/i&gt; [3]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;An association declares that there can be links between instances of the associated types. It has at least two ends represented by properties, each of which is connected to the type of the end. An association declares that there can be links between instances of the associated types.&amp;nbsp;&lt;/i&gt;[4]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;There are other forms of containment that do not have whole / part implications. For example, Each Window refers back to its parent Frame. This is not aggregation since it is not reasonable to consider a parent Frame to be part of a child Window. We use the association relationship to depict this. (...) An association is nothing but a line drawn between the participating classes. (...) Once again note the name on the role. This relationship will almost certainly be implemented with a pointer of some kind. &lt;/i&gt;[5]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;What is the difference between an aggregation and an association? The difference is one of implication. Aggregation denotes whole/part relationships whereas associations do not. However, there is not likely to be much difference in the way that the two relationships are implemented. That is, it would be very difficult to look at the code and determine whether a particular relationship ought to be aggregation or association. For this reason, it is pretty safe to ignore the aggregation relationship altogether. As the amigos said in the UML 0.8 document: “...if you don’t understand&amp;nbsp;[aggregation] don’t use it.” &lt;/i&gt;[5]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Aggregation and Association both correspond to the Has-by-reference relationship from the Booch-94 notation.&lt;/i&gt; [5]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;There are other types of relationships that do not fit neatly into a generalization (a-kind-of) or aggregation (a-part-of) framework. Technically speaking, these relationships are usually a weaker form of the aggregation relationship. For example, a patient schedules an appointment. It could be argued that a patient is a-part-of an appointment. However, there is a clear semantic difference between this type of relationship and one that models the relationship between doors and cars or even workers and unions. As such, they are simply considered to be associations between instances of classes.&lt;/i&gt; [6]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Association: Objects of one class are associated with objects of another class.&lt;/i&gt; [7]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Association is a weak form of connection: the objects may be part of a group, or family, of objects but they’re not completely dependent on each other. For example, consider a car, a driver, a passenger and another passenger. When the driver and the two passengers are in the car, they’re associated: they all go in the same direction, they occupy the same&amp;nbsp;volume in space, and so on. But the association is loose: the driver can drop off one of the passengers to go their separate way, so that the passenger is no longer associated with the other objects.&lt;/i&gt; [7]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;According to the UML standard, all run-time relationships come under the umbrella term association. However, most people use the term ‘association’ to mean ‘an association that isn’t aggregation or composition’. Choosing between relationships can be tricky – you need to use intuition, experience and guesswork. During analysis, you should expect the frequency of these kinds of relationship to be: association &amp;gt; aggregation &amp;gt; inheritance &amp;gt; composition. As far as design and implementation are concerned, the differences between association, aggregation and composition can be difficult to spot.&lt;/i&gt; [7]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;All relationships, except inheritance, can be given an association label, indicating the nature of the association. If it’s not obvious which way the association name should be read, a black arrowhead can be used.&lt;/i&gt; [7]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;As well as association names, we can show roles. A role indicates the part played by an object in the association – the role is shown as a label near the object that plays the role.&lt;/i&gt; [7]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;An association is a relationship between types (or more specifically, instances of those types) that indicates some meaningful and interesting connection.&lt;/i&gt; [9]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;In the UML associations are defined as "the semantic relationship between two or more classifiers that involve connections among their instances."&lt;/i&gt; [9]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Associations worth noting usually imply knowledge of a relationship that needs to be preserved for some duration — it could be milliseconds or years, depending on context. In other words, between what objects do we need to have some memory of a relationship? (...) Associations for which knowledge of the relationship needs to be preserved for some duration ("need-to-know" associations).&lt;/i&gt; [9]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Focus on those associations for which knowledge of the relationship needs&amp;nbsp;to be preserved for some duration ("need-to-know" associations).&lt;/i&gt; [9]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;We should add those associations which the requirements (for example, use cases) suggest or imply a need to remember, or which otherwise are strongly suggested in our perception of the problem domain.&lt;/i&gt; [9]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;An attribute is related to an association&lt;/i&gt; [9]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;How to Discover Associations: During system use-case interviews, look out for statements of the form X [verb] Y, where X and Y represent business objects. They often reveal associations. For example, in “A Peace Committee supervises a Case,” Peace Committee is associated with Case; the association name is supervises.&lt;/i&gt; [10]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;An association represents a relationship that has a precisely defined meaning. The association can be labeled with the name of the association. If you want to assign a direction to the association's name, you can insert a triangle that points to the direction in which the name is supposed to be read. (...) An association indicates that objects of one class have a relationship with objects of another class, in which this connection has a specifically defined meaning (for example, "is flown with").&lt;/i&gt;&amp;nbsp;[11]&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;&lt;span style="font-size: large;"&gt;&lt;b&gt;Aggregation&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Aggregation is a stronger version of association. Unlike  association, aggregation typically implies ownership and may imply a relationship between lifelines. Aggregations are usually read as "...owns a...".  For example, if you had a classed named Window that stored its position  and size in a Rectangle class, you would say the "Window owns  a Rectangle." The rectangle may be shared with other classes, but the Window has an intimate relationship with the Rectangle. This  is subtly different from a basic association; it has a stronger connotation.  However, it's not the strongest relationship you can have between classes. If  the relationship is more of a whole part (class A "...is part of..." class B),  you should look at composition. &lt;/i&gt;[1]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;You show an aggregation with a diamond shape next to the owning  class and a solid line pointing to the owned class.&amp;nbsp;&lt;/i&gt;[1]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Aggregation is the part-of relationship. It's like saying that a car has an engine and wheels as its parts. This sounds good, but the difficult thing is considering what the difference is between aggregation and association. &lt;/i&gt;[2]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;(...) Aggregation is strictly meaningless; as a result, I recommend that you ignore it in your own diagrams. If you see it in other people's diagrams, you'll need to dig deeper to find out what they mean by it. Different authors and teams use it for very different purposes.&amp;nbsp;&lt;/i&gt;[2]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Sometimes a class consists of a number of component classes. This is a special type of relationship called an aggregation. The components and the class they constitute are in a part-whole association. &lt;/i&gt;[3]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Aggregation is a type of association. An aggregate object consists of a set of component objects. &lt;/i&gt;[3]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Aggregation is transitive&lt;/i&gt; [3]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;The weak form of aggregation is denoted with an open diamond. This relationship denotes that the aggregate class (the class with the white diamond touching it) is in some way the “whole”, and the other class in the relationship is somehow “part” of that whole.&lt;/i&gt; [5]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Many different types of aggregation or composition relationships have been proposed in data modeling, knowledge representation, and linguistics. For example, a-part-of (logically or physically), a-member-of (as in set membership), containedin, related-to, and associated-with. However, generally speaking, all aggregation relationships relate parts to wholes or parts to assemblies. For our purposes, we use the a-part-of or has-parts semantic relationship to represent the aggregation abstraction. For example, a door is a-partof a car, an employee is a-part-of a department, or a department is a-part-of an organization.&lt;/i&gt; [6]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Like the generalization relationship, aggregation relationships can be combined into aggregation hierarchies. For example, a piston is a-part-of an engine, while an engine is a-part-of a car.&lt;/i&gt; [6]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Aggregation means putting objects together to make a bigger object. Manufactured items usually form aggregations: for example, a microwave is made up of a cabinet, a door, an indicator panel, buttons, a motor, a glass plate, a magnetron, and so on. Aggregations usually form a part–whole hierarchy. Aggregation implies close dependency, at least of the whole to the part; for example, a magnetron is still a magnetron if you take it out of its microwave, but the microwave would be useless without the magnetron, because it wouldn’t be able to cook anything.&lt;/i&gt; [7]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;As suggested, the distinction between association and aggregation can be subtle. The ‘What happens if you remove one of the objects?’ test can be helpful, but it doesn’t always solve the problem: hard thinking and experience are often needed.&lt;/i&gt; [7]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Aggregation: Strong association – an instance of one class is made up of instances of another class.&lt;/i&gt; [7]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;An aggregation is a special kind of association — a "whole/part" relationship within which one or more classes are  parts of a larger whole. A class can be aggregated to one or more other classes. &lt;br /&gt;
&lt;br /&gt;
Using aggregation is an excellent way to establish a "pecking  order" of complexity, with more complex classes aggregating less complex ones.  For a system of any size, doing this can only help viewers of your models more  easily understand the concepts that are important to them while enabling them to ignore concepts expressed at lower levels of detail.&lt;br /&gt;
&lt;br /&gt;
An aggregation appears as a line with an open diamond at one end. The class next to the diamond is the whole class; the class at the other end of the line is the part class.&lt;/i&gt; [8]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;An important property of aggregation is that the aggregated classes are still  basically independent of the aggregating class.&lt;/i&gt; [8]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Shared aggregation means that the multiplicity at the composite end may be more than one, and is signified with a hollow diamond. It implies that the part may be simultaneously in many composite instances. (...)&amp;nbsp;For instance, a UML package may be considered to aggregate its elements. But an element may be referenced in more than one package (it is owned by one, and referenced in others), which is an example of shared aggregation.&lt;/i&gt; [9]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;In some cases, the presence of aggregation is obvious—usually in physical assemblies. But sometimes, it is not clear. On aggregation: If in doubt, leave it out. Here are some guidelines that suggest when to show aggregation:&lt;br /&gt;
&lt;br /&gt;
Consider showing aggregation when:&lt;br /&gt;
&lt;br /&gt;
• The lifetime of the part is bound within the lifetime of the composite — there is a create-delete dependency of the part on the whole.&lt;br /&gt;
• There is an obvious whole-part physical or logical assembly.&lt;br /&gt;
• Some properties of the composite propagate to the parts, such as the location.&lt;br /&gt;
• Operations applied to the composite propagate to the parts, such as destruction, movement, recording.&lt;br /&gt;
&lt;br /&gt;
Other than something being an obvious assembly of parts, the next most useful clue is the presence of a create-delete dependency of the part on the whole.&lt;/i&gt; [9]&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;b&gt;Composition&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Composition represents a very strong relationship  between classes, to the point of containment. Composition is used to capture a  whole-part relationship. The "part" piece of the relationship can be involved in  only one composition relationship at any given time.  The lifetime of instances involved in composition relationships is almost always  linked; if the larger, owning instance is destroyed, it almost always destroys  the part piece. UML does allow the part to be associated with a different owner  before destruction, thus preserving its existence, but this is typically an  exception rather than the rule. &lt;/i&gt;[1]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;A composition relationship is usually read as "...is part  of...", which means you need to read the composition from the part to the whole.  For example, if you say that a window in your system must have a titlebar, you can represent this with a  class named Titlebar that "...is part of..." a class named Window. &lt;/i&gt;[1]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;You show a composition relationship using a filled diamond next to the owning class and a solid line pointing to the owned class. &lt;/i&gt;[1]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;The general rule is that, although a class may be a component of many other classes, any instance must be a component of only one owner. The class diagram may show multiple classes of potential owners, but any instance has only a single object as its owner. &lt;/i&gt;[2]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;The "no sharing" rule is the key to composition. Another assumption is that if you delete the "whole", it should automatically ensure that any owned parts also are deleted. &lt;/i&gt;[2]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Composition is a good way of showing properties that own by value, properties to value objects, or properties that have a strong and somewhat exclusive ownership of particular other components. &lt;/i&gt;[2]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;One form of aggregation involves a strong relationship between an aggregate object and its component objects. This is called composition. The key to composition is that the component exists as a component only within the composite object. For example, a shirt is a composite of a body, a collar, sleeves, buttons, buttonholes, and cuffs. Do away with the shirt and the collar becomes useless. Sometimes a component in a composite doesn’t last as long as the composite itself. The leaves on a tree can die out before the tree does. If you destroy the tree, the leaves also die.&lt;/i&gt; [3]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;A composition is a special kind of aggregation. In a composite object the components exist only as part of the composite. (...) A composite is a strong type of aggregation. Each component in a composite can belong to just one whole. The components of a coffee table—the tabletop and the legs—make up a composite. The symbol for a composite is the same as the symbol for an aggregation except the diamond is filled.&lt;/i&gt; [3]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Composition relationships are a strong form of containment or aggregation. Aggregation is a whole/part relationship. In this case, Circle is the whole, and Point is part of Circle. However, composition is more than just aggregation. Composition also indicates that the lifetime of Point is dependent upon Circle. This means that if Circle is destroyed, Point will be destroyed with it. For those of you who are familiar with the Booch-94 notation, this is the Hasby-value relationship. &lt;/i&gt;[5]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Composition is a strong aggregation where the composed object is inside a single composite; the composed object is usually created at the same time as the composite and can be deleted at the same time. In UML, in order to emphasize that composition is stronger than aggregation, we use a black diamond instead of a white one. &lt;/i&gt;[7]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Composition: Strong aggregation – the composed object can’t be shared by other objects and dies with its composer.&lt;/i&gt; [7]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;The difference between aggregation and composition is subtle. The differences relate to object sharing and object lifetimes. Recall that a composed object can never be part of more than one composite and dies with the composite, while an aggregated object can be shared and can outlive its aggregator. Although a car trundles out of the factory with a brand new engine inside, the engine may later be replaced, because it’s worn out, so the engine doesn’t necessarily die with the car; in contrast, the body of the car is an intrinsic part of the car – it’s the soul of the car, if you like, you can’t destroy the car without destroying the body (but you could always take the engine out first). The issue of sharing is not important in this example: although the body could never be part of two cars (not legally, anyway), the engine couldn’t either. &lt;/i&gt;[7]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Composition is a "strong" form of aggregation. There are  two differences between composition and regular aggregation, as follows: Within a composition relationship, the whole and the parts  have coincident lifetimes. This means that if a particular instance of the whole  is destroyed, so are the instances of the parts. A class can only belong to one composition relationship at a  time as a part. &lt;/i&gt;[8]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Composite aggregation, or composition, means that the part is a member of only one composite object, and that there is an existence and disposition dependency of the part on the composite. &lt;/i&gt;[9]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Composition is signified with a filled diamond. It implies that the composite solely owns the part. &lt;/i&gt;[9]&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Generalization&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;A generalization relationship  conveys that the target of the relationship is a general, or less specific, version of the source class or interface. Generalization relationships are often used to pull out commonality between difference classifiers. For example, if you  had a class named Cat and a class named Dog, you can create a  generalization of both of those classes called Animal. A full discussion of how and when to use generalization (especially versus interface realization) is the subject for an object-oriented analysis and design book and isn't covered here. &lt;/i&gt;[1]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Generalizations are usually read as "...is a...", starting from  the more specific class and reading toward the general class. Going back to the Cat and Dog example, you would say "a Cat...is a...Animal" (grammar aside).&lt;/i&gt;[1]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;You show a generalization relationship with a solid line with a closed arrow, pointing from the specific class to the general class. &lt;/i&gt;[1]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;One class (the child class or subclass) can inherit attributes and operations from another (the parent class or superclass). The parent class is more general than the child class. (...) Object-orientation refers to this as inheritance. The UML also refers to this as generalization. (...) In the UML, you represent inheritance with a line that connects the parent class to the child class. On the part of the line that connects to the parent class, you put an open triangle that points to the parent class. This type of connection stands for the phrase "is a kind of". &lt;/i&gt;[3]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;The generalization abstraction enables the analyst to create classes that inherit attributes and operations of other classes. The analyst creates a superclass that contains the basic attributes and operations that will be used in several subclasses. The subclasses inherit the attributes and operations of their superclass and can also contain attributes and operations that are unique just to them. For example, a customer class and an employee class can be generalized into a person class by extracting the attributes and operations they have in common and placing them into the new superclass, Person. In this way, the analyst can reduce the redundancy in the class definitions so that the common elements are defined once and then reused in the subclasses. Generalization is represented with the a-kind-of relationship, so that we say that an employee is a-kind-of person.&lt;/i&gt; [6]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Inheritance: A subclass inherits all of the attributes and behavior of its superclass(es). &lt;/i&gt;[7]&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Generalization refers to a relationship between a general class (the superclass or parent) and a more specific version of that class (the subclass or child). You can think of the subclass as being a "kind of" the superclass. A generalization appears as a line with an open triangle at one end. The class next to the triangle is the parent/superclass; the class at the other end of the line is the child/subclass. &lt;/i&gt; [8]&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span style="font-size: large;"&gt;Realization&amp;nbsp;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;A realization is an association between a class and an interface, a collection of operations that a number of classes can use. An interface is represented as a class with no attributes. To distinguish it from a class whose attributes have been elided from the diagram, the keyword «interface» appears above the interface’s name or an uppercase “I” precedes the interface’s name. Realization is represented in the UML as a dashed line that connects the class to the interface, with an open triangle adjoining the interface and pointing to it.&lt;/i&gt; [3]&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;References:&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
[1]&amp;nbsp;Dan Pilone, Neil Pitman, &lt;b&gt;&lt;i&gt;UML 2.0 in a Nutshell&lt;/i&gt;&lt;/b&gt;,&amp;nbsp;O'Reilly, 2005&lt;br /&gt;
[2]&amp;nbsp;Martin Fowler, &lt;b&gt;&lt;i&gt;UML Distilled: A brief guide to the standard object modeling language&lt;/i&gt;&lt;/b&gt;, 3rd edition, Addison-Wesley Professional, 2004&lt;br /&gt;
[3] Joseph Schmuller, &lt;b&gt;&lt;i&gt;Teach Yourself UML in 24 Hours&lt;/i&gt;&lt;/b&gt;, Sams Publishing, 2004&lt;br /&gt;
[4]&amp;nbsp;&lt;b&gt;&lt;i&gt;OMG UML Superstructure Version 2.4.1&lt;/i&gt;&lt;/b&gt;, OMG, 2011&lt;br /&gt;
[5]&amp;nbsp;Robert C. Martin, &lt;b&gt;&lt;i&gt;UML Tutorial&lt;/i&gt;&lt;/b&gt;&lt;br /&gt;
[6] Alan Dennis, Barbara Haley Wixom and David Tegarden, &lt;b&gt;&lt;i&gt;System Analysis and Design with UML Version 2.0 - An Object-Oriented Approach&lt;/i&gt;&lt;/b&gt;, John Wiley &amp;amp; Sons Ltd,&amp;nbsp;2005&lt;br /&gt;
[7]&amp;nbsp;Mike O’Docherty, &lt;b&gt;&lt;i&gt;Object-Oriented&amp;nbsp;Analysis and Design &amp;nbsp;-&amp;nbsp;Understanding System Development&amp;nbsp;with UML 2.0&lt;/i&gt;&lt;/b&gt;,&amp;nbsp;John Wiley &amp;amp; Sons Ltd, 2005&lt;br /&gt;
[8]&amp;nbsp;Kendall Scott, &lt;b&gt;&lt;i&gt;Fast Track UML 2.0&lt;/i&gt;&lt;/b&gt;, Apress, 2004&lt;br /&gt;
[9] Craig Larman, &lt;b&gt;&lt;i&gt;Applying UML and Patterns - An Introduction to Object-Oriented Analysis and Design and the Unified Process&lt;/i&gt;&lt;/b&gt; 2nd ed, Prentice Hall, 2001&lt;br /&gt;
[10]&amp;nbsp;Howard Podeswa, &lt;b&gt;&lt;i&gt;UML for the IT&amp;nbsp;Business Analyst:&amp;nbsp;A Practical Guide to&amp;nbsp;Object-Oriented&amp;nbsp;Requirements Gathering&lt;/i&gt;&lt;/b&gt;,&amp;nbsp;Thomson Course Technology PTR,&amp;nbsp;2005&lt;br /&gt;
[11]&amp;nbsp;Patrick Grässle,&amp;nbsp;Henriette Baumann,&amp;nbsp;Philippe Baumann, &lt;b&gt;&lt;i&gt;UML 2.0 in Action - A Project-Based Tutorial&lt;/i&gt;&lt;/b&gt;,&amp;nbsp;Packt Publishing Ltd, 2005&lt;br /&gt;
[12] Scott W. Ambler, &lt;b&gt;&lt;i&gt;The Elements of UML 2.0 Style&lt;/i&gt;&lt;/b&gt;, Cambridge University Press, 2005&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4912226416400969049-6263918439954648098?l=bojan-komazec.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/msx95wqQ854DMj95XgLajkhuRoI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/msx95wqQ854DMj95XgLajkhuRoI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/msx95wqQ854DMj95XgLajkhuRoI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/msx95wqQ854DMj95XgLajkhuRoI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/MyPublicNotepad/~4/WBEjj0jipus" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://bojan-komazec.blogspot.com/feeds/6263918439954648098/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4912226416400969049&amp;postID=6263918439954648098" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/6263918439954648098?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/6263918439954648098?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyPublicNotepad/~3/WBEjj0jipus/uml-class-diagrams-and-class.html" title="UML Class Diagrams and Class Relationships" /><author><name>Bojan Komazec</name><uri>https://profiles.google.com/117174187628268281803</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://bojan-komazec.blogspot.com/2012/01/uml-class-diagrams-and-class.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkEFQ387cCp7ImA9WhRVGEU.&quot;"><id>tag:blogger.com,1999:blog-4912226416400969049.post-7874198912083885590</id><published>2012-01-18T09:56:00.000Z</published><updated>2012-01-18T09:56:52.108Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-18T09:56:52.108Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><title>Circular references in constructors</title><content type="html">It is not uncommon to have situation when class A references class B and vice versa. This is known as &lt;a href="http://en.wikipedia.org/wiki/Circular_dependency"&gt;circular dependency&lt;/a&gt; and is resolved by using forward declarations. &lt;br /&gt;
&lt;br /&gt;
It is valid and safe to use mutually referenced classes if we initialize references after fully creating classes' instances. But what happens if references are assigned (and probably used) in constructors? Constructor of first class initializes reference to an instance of the second class that is yet to be created...This sounds silly and we can expect all sorts of things - from compile-time and run-time errors to programs running perfectly fine (well, if we are lucky enough...).&lt;br /&gt;
&lt;br /&gt;
References can be implemented as pointer or reference types. &lt;br /&gt;
&lt;br /&gt;
Let's have a look at pointer-based implementation and let us assume we have structures (or classes) implemented like this: &lt;br /&gt;
&lt;br /&gt;
S1.h:&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#ifndef S1_H
#define S1_H

struct S2;

struct S1
{
   S2* m_pS2;
   int m_n;

   S1(S2* pS2);
   void Foo();
   void PrintVal();
};

#endif // S1_H
]]&gt;
&lt;/script&gt;&lt;br /&gt;
S1.cpp:&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#include "S1.h"
#include "S2.h"

#include &lt;iostream&gt;

S1::S1(S2* pS2) : m_pS2(pS2), m_n(1)
{
   std::cout &lt;&lt; "S1::S1()" &lt;&lt; std::endl;

   m_pS2-&gt;Foo();
   m_pS2-&gt;PrintVal();
}

void S1::Foo()
{
   std::cout &lt;&lt; "S1::Foo()" &lt;&lt; std::endl;
}

void S1::PrintVal()
{
   std::cout &lt;&lt; "S1::PrintVal(): " &lt;&lt; m_n &lt;&lt; std::endl;
}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
S2.h:&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#ifndef S2_H
#define S2_H

struct S1;

struct S2
{
   S1* m_pS1;
   int m_n;

   S2(S1* pS1);
   void Foo();
   void PrintVal();
};

#endif // S2_H
]]&gt;
&lt;/script&gt;&lt;br /&gt;
S2.cpp:&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#include "S1.h"
#include "S2.h"

#include &lt;iostream&gt;

S2::S2(S1* pS1) : m_pS1(pS1), m_n(2)
{
   std::cout &lt;&lt; "S2::S2()" &lt;&lt; std::endl;

   m_pS1-&gt;Foo();
   m_pS1-&gt;PrintVal();
}

void S2::Foo()
{
   std::cout &lt;&lt; "S2::Foo()" &lt;&lt; std::endl;
}

void S2::PrintVal()
{
   std::cout &lt;&lt; "S2::PrintVal(): " &lt;&lt; m_n &lt;&lt; std::endl;
}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
main.cpp:&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#include "S1.h"
#include "S2.h"

int main()
{
   S1 s1(0);  
   S2 s2(&amp;s1);
   return 0;
}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
We had to pass &lt;b&gt;0&lt;/b&gt; to &lt;b&gt;S1&lt;/b&gt; constructor as &lt;b&gt;s2&lt;/b&gt; had not yet been declared nor created. This makes &lt;b&gt;S1&lt;/b&gt; constructor to raise &lt;i&gt;access violation&lt;/i&gt; exception when it tries to dereference &lt;b&gt;m_pS2&lt;/b&gt; in order to call &lt;b&gt;S2&lt;/b&gt; methods. &lt;br /&gt;
&lt;br /&gt;
If we used references instead of pointers, we would not even have a chance to write the code that compiles: &lt;br /&gt;
&lt;br /&gt;
S3.h:&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#ifndef S3_H
#define S3_H

struct S4;

struct S3
{
   S4&amp; m_s4;
   int m_n;

   S3(S4&amp; s4);
   void Foo();
   void PrintVal();
};

#endif // S3_H
]]&gt;
&lt;/script&gt;&lt;br /&gt;
S3.cpp:&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#include "S3.h"
#include "S4.h"

#include &lt;iostream&gt;

S3::S3(S4&amp; s4) : m_s4(s4), m_n(1)
{
   std::cout &lt;&lt; "S3::S3()" &lt;&lt; std::endl;

   m_s4.Foo();
   m_s4.PrintVal();
}

void S3::Foo()
{
   std::cout &lt;&lt; "S3::Foo()" &lt;&lt; std::endl;
}

void S3::PrintVal()
{
   std::cout &lt;&lt; "S3::PrintVal(): " &lt;&lt; m_n &lt;&lt; std::endl;
}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
S4.h:&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#ifndef S4_H
#define S4_H

struct S3;

struct S4
{
   S3&amp; m_s3;
   int m_n;

   S4(S3&amp; s3);
   void Foo();
   void PrintVal();
};

#endif // S4_H
]]&gt;
&lt;/script&gt;&lt;br /&gt;
S4.cpp:&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#include "S4.h"
#include "S3.h"

#include &lt;iostream&gt;

S4::S4(S3&amp; s3) : m_s3(s3), m_n(2)
{
   std::cout &lt;&lt; "S4::S4()" &lt;&lt; std::endl;

   m_s3.Foo();
   m_s3.PrintVal();
}

void S4::Foo()
{
   std::cout &lt;&lt; "S4::Foo()" &lt;&lt; std::endl;
}

void S4::PrintVal()
{
   std::cout &lt;&lt; "S4::PrintVal(): " &lt;&lt; m_n &lt;&lt; std::endl;
}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
main.cpp:&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#include "S3.h"
#include "S4.h"

int main()
{
   S3 s3(???); // we cannot pass 0 like we did for pointer member 
   S4 s4(&amp;s3);
   return 0;
}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
A simple fact that we cannot have a reference (or address) of the object that hasn't yet been created leads to conclusion that it is impossible to create instances of mutually dependent classes where references must be initialized in constructor.  &lt;br /&gt;
&lt;br /&gt;
But there is one case when this is actually possible. Possible but not safe. If these structures are members of another (container) structure, it is possible to initialize references in container's constructor initializer list.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
main.cpp:&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#include "S1.h"
#include "S2.h"
#include "S3.h"
#include "S4.h"

struct S5
{
   S1 m_s1; 
   S2 m_s2;

   S5() : m_s1(&amp;m_s2), m_s2(&amp;m_s1){}

   void PrintVals()
   {
      std::cout &lt;&lt; "S5::PrintVals()" &lt;&lt; std::endl;

      m_s1.m_pS2-&gt;PrintVal();
      m_s2.m_pS1-&gt;PrintVal();
   }
};

struct S6
{
   S3 m_s3; 
   S4 m_s4;

   S6() : m_s3(m_s4), m_s4(m_s3){}

   void PrintVals()
   {   
      std::cout &lt;&lt; "S6::PrintVals()" &lt;&lt; std::endl;

      m_s3.m_s4.PrintVal();
      m_s4.m_s3.PrintVal();
   }
};

int main()
{
   S5 s5;
   s5.PrintVals();

   S6 s6;
   s6.PrintVals();
   return 0;
}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
Output:&lt;br /&gt;
&lt;div class="cmd_line"&gt;S1::S1()&lt;br /&gt;
S2::Foo()&lt;br /&gt;
S2::PrintVal(): -858993460&lt;br /&gt;
S2::S2()&lt;br /&gt;
S1::Foo()&lt;br /&gt;
S1::PrintVal(): 1&lt;br /&gt;
S5::PrintVals()&lt;br /&gt;
S2::PrintVal(): 2&lt;br /&gt;
S1::PrintVal(): 1&lt;br /&gt;
S3::S3()&lt;br /&gt;
S4::Foo()&lt;br /&gt;
S4::PrintVal(): -858993460&lt;br /&gt;
S4::S4()&lt;br /&gt;
S3::Foo()&lt;br /&gt;
S3::PrintVal(): 1&lt;br /&gt;
S6::PrintVals()&lt;br /&gt;
S4::PrintVal(): 2&lt;br /&gt;
S3::PrintVal(): 1&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
We can see here that:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;It is possible to &lt;i&gt;set&lt;/i&gt; circular references between two classes during their construction if they are members of some container class&lt;br /&gt;
&lt;li&gt;It is not safe to &lt;i&gt;use&lt;/i&gt; circular references in constructors of their classes: dereferencing (and using) reference of the object that is not fully constructed leads to undefined behaviour. In our examples, the wrong value of the member of the class that had not yet been constructed was printed (-858993460 instead of 2)&lt;br /&gt;
&lt;li&gt;It is safe to &lt;i&gt;use&lt;/i&gt; circular references once objects are fully created &lt;b&gt;S5::PrintVals()&lt;/b&gt; and &lt;b&gt;S6::PrintVals()&lt;/b&gt; print correct values of members of referenced objects. This is similar to the case when some container class &lt;b&gt;A&lt;/b&gt; has a member &lt;b&gt;B&lt;/b&gt; that must be initialized with the pointer/reference to &lt;b&gt;A&lt;/b&gt; (&lt;b&gt;this&lt;/b&gt; or &lt;b&gt;*this&lt;/b&gt;): that is safe as long as &lt;b&gt;B&lt;/b&gt;'s constructor doesn't try to access &lt;b&gt;A&lt;/b&gt;'s members or call &lt;b&gt;A&lt;/b&gt;'s methods. &lt;b&gt;B&lt;/b&gt; has to wait for &lt;b&gt;A&lt;/b&gt; to be completely constructed in order to use &lt;b&gt;A&lt;/b&gt;'s reference safely&lt;br /&gt;
&lt;/ul&gt;One additional note: it is always a good practice to decouple classes (break dependencies between them) as much as possible. This is usually done by using interfaces or some other patterns (e.g. Observer pattern).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4912226416400969049-7874198912083885590?l=bojan-komazec.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/CfUF8lI1XXovFJ5m1WZVTT7yAAc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CfUF8lI1XXovFJ5m1WZVTT7yAAc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/CfUF8lI1XXovFJ5m1WZVTT7yAAc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/CfUF8lI1XXovFJ5m1WZVTT7yAAc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/MyPublicNotepad/~4/nAlPm3F0Xo8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://bojan-komazec.blogspot.com/feeds/7874198912083885590/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4912226416400969049&amp;postID=7874198912083885590" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/7874198912083885590?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/7874198912083885590?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyPublicNotepad/~3/nAlPm3F0Xo8/circular-references-in-constructors.html" title="Circular references in constructors" /><author><name>Bojan Komazec</name><uri>https://profiles.google.com/117174187628268281803</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://bojan-komazec.blogspot.com/2012/01/circular-references-in-constructors.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0QMQXgzfCp7ImA9WhRVEk0.&quot;"><id>tag:blogger.com,1999:blog-4912226416400969049.post-2608030365516494605</id><published>2012-01-10T12:38:00.000Z</published><updated>2012-01-10T14:23:00.684Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-10T14:23:00.684Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><title>Prefer compile-time to run-time value range checks: use enumerations</title><content type="html">In a perfect world, compiler should be able to detect all errors in the code. If types mismatch or value is out of the valid range - compiler should complain. How can we help compiler to achieve this? One answer is: by defining our custom types.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Enumerations&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
When we define enumeration, we are introducing a new type. Let's say some integer variable can be assigned only certain values, from a predefined set. Function that assigns value to a variable could look like this:&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
// nLevel can have only following values: -1, 0 and 1
int nLevel;

void SetLevel(int n)
{   
   nLevel = n;
};
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
Ok, what happens if someone writes &lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
SetLevel(2);
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
This code compiles fine but it sets variable to a value out of the valid range and this can lead to some logical errors.&lt;br /&gt;
&lt;br /&gt;
How can we improve this code? Obviously, we can check whether value is valid. If it is not, we can either throw exception, set variable to some default value or just quietly return from a function:&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
void SetLevel(int n)
{  
   if((n &lt; -1) || (n &gt; 1))
      throw 1;

   nLevel = n;
};
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
Each time this function is called it will use CPU resources to perform value check. But is it necessary? Can we make this function more optimal in a run-time? Yes, we can: by moving value check from run-rime to compile time! If we define our custom type - enumeration - which defines valid range, we will be able to use compiler to find all places where invalid value is passed:&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
enum Level
{
   NEGATIVE = -1,
   ZERO = 0,
   POSITIVE = 1
};

Level level;

void SetLevel(Level l)
{   
   level = l;
};
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
SetLevel(2) will cause compiler to report an error. &lt;br /&gt;
&lt;br /&gt;
One example of the real-life usage of this approach could be writing a wrapper around Windows Thread API. E.g. &lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms686277(v=VS.85).aspx"&gt;&lt;b&gt;SetThreadPriority&lt;/b&gt;&lt;/a&gt; has an argument &lt;b&gt;nPriority&lt;/b&gt; which is of type &lt;b&gt;int&lt;/b&gt; and so can accept any integer value despite the fact that valid values are from a predefined set (&lt;b&gt;THREAD_PRIORITY_ABOVE_NORMAL&lt;/b&gt; = 1, &lt;b&gt;THREAD_PRIORITY_BELOW_NORMAL&lt;/b&gt; = -1, &lt;b&gt;THREAD_PRIORITY_HIGHEST&lt;/b&gt; = 2, ...). Passing invalid integer values can be prevented by introducing our enumeration which enumerates all valid values for thread priority:&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
enum ThreadPriority
{
 ThreadModeBackgroundBegin = THREAD_MODE_BACKGROUND_BEGIN,
 ThreadModeBackgroundEnd = THREAD_MODE_BACKGROUND_END,
 ThreadPriorityAboveNormal = THREAD_PRIORITY_ABOVE_NORMAL, 
 ThreadPriorityBelowNormal = THREAD_PRIORITY_BELOW_NORMAL,
 ThreadPriorityHighest = THREAD_PRIORITY_HIGHEST,
 ThreadPriorityIdle = THREAD_PRIORITY_IDLE,
 ThreadPriorityLowest = THREAD_PRIORITY_LOWEST,
 ThreadPriorityNormal = THREAD_PRIORITY_NORMAL,
 ThreadPriorityCritical = THREAD_PRIORITY_TIME_CRITICAL
};

class CThread
{
   ...
   HANDLE m_hThread;  
   ...
public:   
   ...
   void SetPriority(ThreadPriority priority)
   {
      ...
      SetThreadPriority(m_hThread, priority);
      ...
   };
   ...
};
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
NOTE: &lt;b&gt;enum&lt;/b&gt; value is implicitly casted to &lt;b&gt;int&lt;/b&gt; but &lt;b&gt;int&lt;/b&gt; value must be explicitly casted to &lt;b&gt;enum&lt;/b&gt; type.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4912226416400969049-2608030365516494605?l=bojan-komazec.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/i6e0ckKZnsKuTrjacx3Hi9u9_mk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/i6e0ckKZnsKuTrjacx3Hi9u9_mk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/i6e0ckKZnsKuTrjacx3Hi9u9_mk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/i6e0ckKZnsKuTrjacx3Hi9u9_mk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/MyPublicNotepad/~4/aORmJMNnk5w" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://bojan-komazec.blogspot.com/feeds/2608030365516494605/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4912226416400969049&amp;postID=2608030365516494605" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/2608030365516494605?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/2608030365516494605?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyPublicNotepad/~3/aORmJMNnk5w/prefer-compile-time-to-run-time-value.html" title="Prefer compile-time to run-time value range checks: use enumerations" /><author><name>Bojan Komazec</name><uri>https://profiles.google.com/117174187628268281803</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total><feedburner:origLink>http://bojan-komazec.blogspot.com/2012/01/prefer-compile-time-to-run-time-value.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkENRXo6eip7ImA9WhRXEEg.&quot;"><id>tag:blogger.com,1999:blog-4912226416400969049.post-4334913256615113014</id><published>2011-12-16T17:43:00.000Z</published><updated>2011-12-16T18:04:54.412Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-16T18:04:54.412Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Design Patterns" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><title>Finite State Machine in C++</title><content type="html">In my article &lt;a href="http://bojan-komazec.blogspot.com/2011/10/finite-state-machine-in-c.html"&gt;"Finite State Machine in C"&lt;/a&gt; I gave a short introduction to Finite State Machines (FSM) and demonstrated two possible implementations of the Car state machine model. &lt;br /&gt;
&lt;br /&gt;
In this article I will show C++ implementation of the same model, by using &lt;a href="http://en.wikipedia.org/wiki/State_pattern"&gt;&lt;b&gt;State Pattern&lt;/b&gt;&lt;/a&gt;. All state classes are derived from an abstract base class &lt;b&gt;CState&lt;/b&gt; and each of them implements public method &lt;b&gt;HandleEvent(EVENT evt)&lt;/b&gt;. &lt;b&gt;CSMManager&lt;/b&gt; class is a State Machine Manager and represents the core of our State Machine: it receives events and dispatches them to the current state for handling. Its  private member &lt;b&gt;m_pCurrState&lt;/b&gt; is a pointer to the &lt;b&gt;CState&lt;/b&gt; base class but it always points to actual state objects. State transition is implemented as its reassignment to a different state object (object's address). This happens when some event occurs. Behaviour of this model is event-driven and, in contrast to C implementations, state transition control is not centralized here - it is not the State Manager who takes care of which state is going to be the next one. Current state decides on that itself, depending on its current conditions and events it receives.&lt;br /&gt;
&lt;br /&gt;
Events.h:&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#ifndef EVENTS_H
#define EVENTS_H

#include &lt;string&gt;
using std::string;

enum EVENT
{
 EVENT_IGNITE,
 EVENT_ACCELERATE, 
 EVENT_BRAKE,
 EVENT_TURN_OFF
};

static string events[]  = {
 string("EVENT_IGNITE"),
 string("EVENT_ACCELERATE"),
 string("EVENT_BRAKE"), 
 string("EVENT_TURN_OFF")
};

#endif // EVENTS_H
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
States.h:&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#ifndef STATES_H
#define STATES_H

#include &lt;string&gt;
using std::string;

enum STATE
{ 
 STATE_INVALID,
 STATE_TURNED_OFF,
 STATE_IDLE, 
 STATE_MOVING
};

static string states[]  = {
 string("STATE_INVALID"),
 string("STATE_TURNED_OFF"),
 string("STATE_IDLE"), 
 string("STATE_MOVING")
};

#endif // STATES_H
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
State.h:&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#ifndef STATE_H
#define STATE_H

#include "States.h"
#include "Events.h"

class CSMManager;

class CState
{
protected:
 STATE m_nID;

 // States inherited from this class can access State Manager 
 // through this member 
 CSMManager&amp; m_SMManager;

public: 
 CState(CSMManager&amp; SMManager, STATE nID) : m_SMManager(SMManager), m_nID(nID){}
 const STATE GetID() const {return m_nID;}
 
 virtual void OnEntry() = 0;

 // this function is executed each time current state receives some event
 virtual void HandleEvent(EVENT evt) = 0; 

 virtual void OnExit() = 0;
 
};

#endif // STATE_H
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
StateTurnedOff.h:&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#ifndef STATETURNEDOFF_H
#define STATETURNEDOFF_H

#include "State.h"
#include "States.h"

class CStateTurnedOff : public CState
{ 
public:
 CStateTurnedOff(CSMManager&amp; SMManager); 
 void OnEntry();
 void HandleEvent(EVENT evt);
 void OnExit();
};

#endif // STATETURNEDOFF_H
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
StateTurnedOff.cpp:&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#include "StateTurnedOff.h"
#include "SMManager.h"
#include &lt;iostream&gt;
using std::cout;
using std::endl;

CStateTurnedOff::CStateTurnedOff(CSMManager&amp; SMManager) : 
 CState(SMManager, STATE_TURNED_OFF)
{
}

void CStateTurnedOff::OnEntry()
{
 cout &lt;&lt; "\nCStateTurnedOff::OnEntry()" &lt;&lt; endl;
}

void CStateTurnedOff::HandleEvent(EVENT evt)
{
 switch(evt)
 {  
 case EVENT_IGNITE:
  m_SMManager.Ignited();
  m_SMManager.ChangeState(STATE_IDLE);
  break;
 case EVENT_ACCELERATE:
  m_SMManager.DoNothing();
  break;
 case EVENT_BRAKE:
  m_SMManager.DoNothing();
  break;
 case EVENT_TURN_OFF:
  m_SMManager.DoNothing();
  break;
 default:
  break;
 }
}

void CStateTurnedOff::OnExit()
{
 cout &lt;&lt; "CStateTurnedOff::OnExit()" &lt;&lt; endl;
}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
StateIdle.h:&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#ifndef STATEIDLE_H
#define STATEIDLE_H

#include "State.h"
#include "States.h"

class CStateIdle : public CState
{ 
public:
 CStateIdle(CSMManager&amp; SMManager); 
 void OnEntry();
 void HandleEvent(EVENT evt);
 void OnExit();
};

#endif // STATEIDLE_H
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
StateIdle.cpp:&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#include "StateIdle.h"
#include "SMManager.h"
#include &lt;iostream&gt;
using std::cout;
using std::endl;

CStateIdle::CStateIdle(CSMManager&amp; SMManager) : 
 CState(SMManager, STATE_IDLE)
{
}

void CStateIdle::OnEntry()
{
 cout &lt;&lt; "\nCStateIdle::OnEntry()" &lt;&lt; endl;
}

void CStateIdle::HandleEvent(EVENT evt)
{
 switch(evt)
 {  
 case EVENT_IGNITE:
  m_SMManager.Complain();
  m_SMManager.ChangeState(STATE_INVALID);
  break;
 case EVENT_ACCELERATE:
  m_SMManager.Accelerating();
  m_SMManager.ChangeState(STATE_MOVING);
  break;
 case EVENT_BRAKE:
  m_SMManager.DoNothing();  
  break;
 case EVENT_TURN_OFF:
  m_SMManager.SayGoodbye();
  m_SMManager.ChangeState(STATE_TURNED_OFF);
  break;
 default:
  break;
 }
}

void CStateIdle::OnExit()
{
 cout &lt;&lt; "CStateIdle::OnExit()" &lt;&lt; endl;
}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
StateMoving.h:&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#ifndef STATEMOVING_H
#define STATEMOVING_H

#include "State.h"
#include "States.h"

class CStateMoving : public CState
{ 
public:
 CStateMoving(CSMManager&amp; SMManager); 
 void OnEntry();
 void HandleEvent(EVENT evt);
 void OnExit();
};

#endif // STATEMOVING_H
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
StateMoving.cpp:&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#include "StateMoving.h"
#include "SMManager.h"
#include &lt;iostream&gt;
using std::cout;
using std::endl;

CStateMoving::CStateMoving(CSMManager&amp; SMManager) : 
 CState(SMManager, STATE_MOVING)
{
}

void CStateMoving::OnEntry()
{
 cout &lt;&lt; "\nCStateMoving::OnEntry()" &lt;&lt; endl;
}

void CStateMoving::HandleEvent(EVENT evt)
{
 switch(evt)
 {  
 case EVENT_IGNITE:
  m_SMManager.Complain();
  m_SMManager.ChangeState(STATE_INVALID);
  break;
 case EVENT_ACCELERATE:
  m_SMManager.Accelerating();
  break;
 case EVENT_BRAKE:
  m_SMManager.Braking();
  m_SMManager.ChangeState(STATE_IDLE);
  break;
 case EVENT_TURN_OFF:
  m_SMManager.Complain();
  m_SMManager.ChangeState(STATE_INVALID);
  break;
 default:
  break;
 }
}

void CStateMoving::OnExit()
{
 cout &lt;&lt; "CStateMoving::OnExit()" &lt;&lt; endl;
}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
StateInvalid.h:&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#ifndef STATEINVALID_H
#define STATEINVALID_H

#include "State.h"
#include "States.h"

class CStateInvalid : public CState
{ 
public:
 CStateInvalid(CSMManager&amp; SMManager); 
 void OnEntry();
 void HandleEvent(EVENT evt);
 void OnExit();
};

#endif // STATEINVALID_H
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
StateInvalid.cpp:&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#include "StateInvalid.h"
#include "SMManager.h"
#include &lt;iostream&gt;
using std::cout;
using std::endl;

CStateInvalid::CStateInvalid(CSMManager&amp; SMManager) : 
 CState(SMManager, STATE_INVALID)
{
}

void CStateInvalid::OnEntry()
{
 cout &lt;&lt; "\nCStateInvalid::OnEntry()" &lt;&lt; endl;
}

void CStateInvalid::HandleEvent(EVENT evt)
{
 switch(evt)
 {  
 case EVENT_IGNITE:  
  break;
 case EVENT_ACCELERATE:
  break;
 case EVENT_BRAKE:
  break;
 case EVENT_TURN_OFF:
  break;
 default:
  break;
 }
}

void CStateInvalid::OnExit()
{
 cout &lt;&lt; "CStateInvalid::OnExit()" &lt;&lt; endl;
}

]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
SMManager.h:&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#ifndef SMMANAGER_H
#define SMMANAGER_H

#include "Events.h"

#include "StateInvalid.h"
#include "StateTurnedOff.h"
#include "StateMoving.h"
#include "StateIdle.h"

class CSMManager
{
 friend class CStateInvalid;
 friend class CStateTurnedOff;
 friend class CStateMoving;
 friend class CStateIdle;

 CSMManager(const CSMManager&amp;);
 CSMManager&amp; operator=(const CSMManager&amp;);

 CStateInvalid m_stateInvalid;
 CStateTurnedOff m_stateTurnedOff;
 CStateMoving m_stateMoving;
 CStateIdle m_stateIdle;

 CState* m_pCurrState; 
 STATE m_prevStateID;

 void ChangeState(STATE newState);

 void Ignited();
 void DoNothing();
 void Complain();
 void Accelerating();
 void SayGoodbye();
 void Braking();

public: 
 CSMManager();
 ~CSMManager();
 void ScheduleEvent(EVENT evt);
};

#endif // SMMANAGER_H
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
SMManager.cpp:&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#include "SMManager.h"
#include &lt;iostream&gt;
using std::cout;
using std::endl;

#pragma warning(push)
#pragma warning(disable: 4355)

CSMManager::CSMManager() : 
 m_stateInvalid(*this),
 m_stateTurnedOff(*this),
 m_stateMoving(*this),
 m_stateIdle(*this),
 m_pCurrState(0)
{
 ChangeState(STATE_TURNED_OFF);
}
#pragma warning(pop)

CSMManager::~CSMManager()
{
 if(m_pCurrState)
 {
  m_pCurrState-&gt;OnExit();
 }

 m_pCurrState = 0;
}

void CSMManager::ScheduleEvent(EVENT evt)
{
 cout &lt;&lt; "Event received: " &lt;&lt; events[evt] &lt;&lt; endl;
 m_pCurrState-&gt;HandleEvent(evt);
}

void CSMManager::ChangeState(STATE newState)
{
 if(m_pCurrState)
 {
  m_pCurrState-&gt;OnExit();
  m_prevStateID = m_pCurrState-&gt;GetID();
 }

 switch(newState)
 {
 case STATE_IDLE:
  m_pCurrState = &amp;m_stateIdle;
  break;
 case STATE_INVALID:
  m_pCurrState = &amp;m_stateInvalid;
  break;
 case STATE_MOVING:
  m_pCurrState = &amp;m_stateMoving;
  break;
 case STATE_TURNED_OFF:
  m_pCurrState = &amp;m_stateTurnedOff;
  break;
 }
 
 m_pCurrState-&gt;OnEntry();
}

void CSMManager::Ignited()
{
 cout &lt;&lt; "\tWhoooa! I'm turned on!" &lt;&lt; endl;
}
 
void CSMManager::DoNothing()
{
 cout &lt;&lt; "\tDon't bother!" &lt;&lt; endl;
}
 
void CSMManager::Complain()
{
 cout &lt;&lt; "\tThis hurts!" &lt;&lt; endl;
}
 
void CSMManager::Accelerating()
{
 cout &lt;&lt; "\tYipee! I'm accelerating!" &lt;&lt; endl;
}
 
void CSMManager::SayGoodbye()
{
 cout &lt;&lt; "\tThat was probably enough..." &lt;&lt; endl;
}
 
void CSMManager::Braking()
{
 cout &lt;&lt; "\tWhoops! Was I too fast?" &lt;&lt; endl;
}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
main.cpp:&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#include "SMManager.h"

void TestStateMachineLifeCycle()
{
 CSMManager SMManager;
 SMManager.ScheduleEvent(EVENT_IGNITE);
 SMManager.ScheduleEvent(EVENT_ACCELERATE);
 SMManager.ScheduleEvent(EVENT_BRAKE);
 SMManager.ScheduleEvent(EVENT_TURN_OFF);
}

int main()
{
 TestStateMachineLifeCycle();
 return 0;
}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
Output:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="cmd_line"&gt;&lt;br /&gt;
CStateTurnedOff::OnEntry()&lt;br /&gt;
Event received: EVENT_IGNITE&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;Whoooa! I'm turned on!&lt;br /&gt;
CStateTurnedOff::OnExit()&lt;br /&gt;
&lt;br /&gt;
CStateIdle::OnEntry()&lt;br /&gt;
Event received: EVENT_ACCELERATE&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;Yipee! I'm accelerating!&lt;br /&gt;
CStateIdle::OnExit()&lt;br /&gt;
&lt;br /&gt;
CStateMoving::OnEntry()&lt;br /&gt;
Event received: EVENT_BRAKE&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;Whoops! Was I too fast?&lt;br /&gt;
CStateMoving::OnExit()&lt;br /&gt;
&lt;br /&gt;
CStateIdle::OnEntry()&lt;br /&gt;
Event received: EVENT_TURN_OFF&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;That was probably enough...&lt;br /&gt;
CStateIdle::OnExit()&lt;br /&gt;
&lt;br /&gt;
CStateTurnedOff::OnEntry()&lt;br /&gt;
CStateTurnedOff::OnExit()&lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
Note that State Manager's member which refers to the current state (&lt;b&gt;m_pCurrState&lt;/b&gt;) is not of reference type (CState&amp;) but a pointer (CState*). This is one of the cases where we MUST use pointer instead of reference because we want to have a variable which reffers to different objects throughout the execution and as re-seating the reference is not allowed, the only option is using a pointer. Please refer &lt;a href="http://www.parashift.com/c++-faq-lite/references.html"&gt;Parashift's FAQ on References&lt;/a&gt; and &lt;a href="http://stackoverflow.com/questions/8449467/dealing-with-assignment-operator-overloads-can-you-re-assign-a-reference"&gt;this SO question&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
The reason for introducing &lt;b&gt;m_prevStateID&lt;/b&gt; is that sometimes state machine (or some of its states) needs to know what was its previous state. Variable which keeps track of the previous state should not be of type reference (m_prevState : CState&amp;) or pointer (m_pPrevState : CState*) as current state should not be able to access (members) of other states. It is therefore enough if it holds only the ID of the previous state.&lt;br /&gt;
&lt;br /&gt;
Note that base abstract class &lt;b&gt;CState&lt;/b&gt; declares &lt;b&gt;OnEntry()&lt;/b&gt; and &lt;b&gt;OnExit()&lt;/b&gt; methods - those which are executed when entering and leaving state. Current state executes &lt;b&gt;HandleEvent(EVENT evt)&lt;/b&gt; each time it receives some event.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4912226416400969049-4334913256615113014?l=bojan-komazec.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/4m74L_myJitpApx8c3yiLXPfyE4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4m74L_myJitpApx8c3yiLXPfyE4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/4m74L_myJitpApx8c3yiLXPfyE4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4m74L_myJitpApx8c3yiLXPfyE4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/MyPublicNotepad/~4/BSnycpVciPc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://bojan-komazec.blogspot.com/feeds/4334913256615113014/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4912226416400969049&amp;postID=4334913256615113014" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/4334913256615113014?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/4334913256615113014?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyPublicNotepad/~3/BSnycpVciPc/finite-state-machine-in-c.html" title="Finite State Machine in C++" /><author><name>Bojan Komazec</name><uri>https://profiles.google.com/117174187628268281803</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://bojan-komazec.blogspot.com/2011/12/finite-state-machine-in-c.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0ABSHk-fSp7ImA9WhRQFE8.&quot;"><id>tag:blogger.com,1999:blog-4912226416400969049.post-3217332499580084846</id><published>2011-12-09T11:06:00.001Z</published><updated>2011-12-09T11:22:39.755Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-09T11:22:39.755Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Endianness" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><title>Endianness: how does CPU read bytes from memory?</title><content type="html">The simplest example is enough to give you the idea: CPU needs to read 2-byte data type from memory. The following example shows how do Big and Little endian machines read variable of type &lt;b&gt;unsigned short&lt;/b&gt; from memory:&lt;br /&gt;
&lt;br /&gt;
main.cpp&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#include &lt;iostream&gt;
int main(int argc, char** argv)
{
 // 0xabcd = 43981
 // 0xcdab = 52651

 // let us assume this is what we have in memory 
 unsigned char arr[2] = {0xab, 0xcd};
 std::cout &lt;&lt; "Memory layout:" &lt;&lt; std::endl;
 std::cout &lt;&lt; "arr[0] = " &lt;&lt; std::hex &lt;&lt; std::showbase &lt;&lt; static_cast&lt;int&gt;(arr[0]) &lt;&lt; std::endl;
 std::cout &lt;&lt; "arr[1] = " &lt;&lt; static_cast&lt;int&gt;(arr[1]) &lt;&lt; std::dec &lt;&lt; std::endl;

 unsigned short val = *reinterpret_cast&lt;unsigned short*&gt;(&amp;arr);
 std::cout &lt;&lt; "val (simple cast on little endian host) = " &lt;&lt; val &lt;&lt; std::endl;
   
 // This is how Little Endian CPU gets value from memory:
 // Little Endian CPU takes the lowest memory (arr[0]) byte as Least Significant Byte (LSB)
 val = static_cast&lt;unsigned short&gt;(arr[0]) + static_cast&lt;unsigned short&gt;(arr[1] &lt;&lt; 8);
 std::cout &lt;&lt; "val (as interpreted by little endian cpu) = " &lt;&lt; val &lt;&lt; std::endl;

 // This is how Big Endian CPU gets value from memory:
 // Big Endian CPU takes the lowest memory (arr[0]) byte as Most Significant Byte (MSB)
 val = static_cast&lt;unsigned short&gt;(arr[1]) + static_cast&lt;unsigned short&gt;(arr[0] &lt;&lt; 8);
 std::cout &lt;&lt; "val (as interpreted by big endian cpu) = " &lt;&lt; val &lt;&lt; std::endl;   

 return 0;
}

]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
Output:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="cmd_line"&gt;Memory layout:&lt;br /&gt;
arr[0] = 0xab&lt;br /&gt;
arr[1] = 0xcd&lt;br /&gt;
val (simple cast on little endian host) = 52651&lt;br /&gt;
val (as interpreted by little endian cpu) = 52651&lt;br /&gt;
val (as interpreted by big endian cpu) = 43981&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4912226416400969049-3217332499580084846?l=bojan-komazec.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ozoCYpYQgu4tX57r2JGmnjV5jX0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ozoCYpYQgu4tX57r2JGmnjV5jX0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ozoCYpYQgu4tX57r2JGmnjV5jX0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ozoCYpYQgu4tX57r2JGmnjV5jX0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/MyPublicNotepad/~4/uYHgG_Dn6Ns" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://bojan-komazec.blogspot.com/feeds/3217332499580084846/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4912226416400969049&amp;postID=3217332499580084846" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/3217332499580084846?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/3217332499580084846?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyPublicNotepad/~3/uYHgG_Dn6Ns/endianness-how-does-cpu-read-bytes-from.html" title="Endianness: how does CPU read bytes from memory?" /><author><name>Bojan Komazec</name><uri>https://profiles.google.com/117174187628268281803</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://bojan-komazec.blogspot.com/2011/12/endianness-how-does-cpu-read-bytes-from.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUcFQ3wzeCp7ImA9WhRQE0s.&quot;"><id>tag:blogger.com,1999:blog-4912226416400969049.post-9184729323715091901</id><published>2011-12-08T10:05:00.001Z</published><updated>2011-12-08T17:56:52.280Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-08T17:56:52.280Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Endianness" /><category scheme="http://www.blogger.com/atom/ns#" term="string" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><category scheme="http://www.blogger.com/atom/ns#" term="Networking" /><category scheme="http://www.blogger.com/atom/ns#" term="Unicode" /><title>Host endianness and data transfer over the network</title><content type="html">Network components talk to each other by sending &lt;b&gt;messages&lt;/b&gt; which are simply arrays of bytes. In order to understand them, parties in conversation need to know the &lt;b&gt;communication protocol&lt;/b&gt; which defines message format and the length, order and the meaning of its parts. &lt;br /&gt;
&lt;br /&gt;
Typically, message would comprise header and payload. &lt;b&gt;Header&lt;/b&gt; can contain information about message itself, protocol version and information about the sender and receiver. &lt;b&gt;Payload&lt;/b&gt; is actually information that sender wants to pass to receiver. &lt;br /&gt;
&lt;br /&gt;
The simplest and shortest message one host can send is a message of a 1-byte length. In this case, protocol only needs to define how is this byte treated - as a character, signed or unsigned number. For example, if protocol says that message contains value of type unsigned char, and the message is 0x8b, receiver will treat this as a positive integer, of value 139. If that was a value of signed char, receiver would understand that this is a negative integer, -117. &lt;br /&gt;
&lt;br /&gt;
There is one problem for messages made of two or more bytes. Bytes are send and received in the same order they are written in the sending buffer. But the way how are bytes copied from register to memory (buffer) and vice versa can be different on different hosts and this depends on their &lt;a href="http://en.wikipedia.org/wiki/Endianness"&gt;endianness&lt;/a&gt;. If sender has a &lt;b&gt;big endian (BE)&lt;/b&gt; CPU and receiver has a &lt;b&gt;small endian (SE)&lt;/b&gt; CPU, receiver might interpret received values in a wrong way. &lt;br /&gt;
&lt;br /&gt;
Let's look at the case when the message comprises of 2-byte integer value, let's say of type unsigned short. This type has a range of values between 0 and 65535 (0x0000 and 0xffff). If BE sender wants to send value 0xabcd (43981) it will copy this value from registry to buffer keeping the same byte order and buffer will be like this: | 0xab | 0xcd |. &lt;b&gt;Most significant byte (MSB)&lt;/b&gt; is at the lower address in memory. The other side will receive bytes in the same order. When copying bytes to the registry, BE receiver will treat the byte from the lowest memory address as the MSB and put it first so the registry will filled with bytes in the same order they are in the memory (0xabcd) and everything would be fine. But LE receiver will treat byte from the lowest address as the &lt;b&gt;Least Significant Byte (LSB)&lt;/b&gt; and put it at the last position in the registry - it would swap the order and read received value as 0xcdab (52651), which is wrong! Sender should know the endianness of the client so can send bytes in the correct order, but that is impractical.&lt;br /&gt;
&lt;br /&gt;
Solution to this is a simple rule: &lt;b&gt;sender should always send bytes in big endian order (network byte order) and receiver should always convert received bytes from network to its own byte order&lt;/b&gt;. This makes sending and receiving code portable.&lt;br /&gt;
&lt;br /&gt;
Both Windows and *NIX networking frameworks offer helper functions which are able to convert integers from host to network byte order and vice versa. They are:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;   uint32_t htonl(uint32_t hostlong);&lt;br /&gt;
uint16_t htons(uint16_t hostshort);&lt;br /&gt;
uint32_t ntohl(uint32_t netlong);&lt;br /&gt;
uint16_t ntohs(uint16_t netshort);&lt;/b&gt;   &lt;br /&gt;
&lt;br /&gt;
Obviously, if host has network byte order (big endian), no conversion would take place, no matter whether it is on the sending or receiving side.&lt;br /&gt;
&lt;br /&gt;
Sending and receiving buffers can be declared as &lt;b&gt;char&lt;/b&gt; or &lt;b&gt;unsigned char&lt;/b&gt; arrays. Values transported could be of &lt;b&gt;signed&lt;/b&gt; or &lt;b&gt;unsigned&lt;/b&gt; types. I made a set of several utility functions that insert and export values of desired integer types into/out from sending/receiving (probably socket) buffers. Prior to inserting, values are converted to network byte order (big endian) and after extraction, values are converted from network to host byte order. Tests prove that &lt;b&gt;hton&lt;/b&gt;/&lt;b&gt;ntoh&lt;/b&gt; functions can be applied both to signed and unsigned types as all they do is actually swapping bytes (if necessary).&lt;br /&gt;
&lt;br /&gt;
NetBuffUtilCore.h:&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#ifndef NETBUFFUTILCORE_H
#define NETBUFFUTILCORE_H

#include &lt;Winsock2.h&gt;
#pragma comment(lib, "Ws2_32.lib")

template &lt;typename T&gt;
void InsertShortVal(char* positionInSendBuff, T val)
{   
 val = htons(val);
 memcpy(positionInSendBuff, &amp;val, sizeof(T)); 
}

template &lt;typename T&gt;
void InsertLongVal(char* positionInSendBuff, T val)
{   
 val = htonl(val);
 memcpy(positionInSendBuff, &amp;val, sizeof(T)); 
}

template &lt;typename T&gt;
void ExtractShortVal(char* positionInRecvBuff, T&amp; val)
{  
 memcpy(&amp;val, positionInRecvBuff, sizeof(T));
 val = ntohs(val);  
}

template &lt;typename T&gt;
void ExtractLongVal(char* positionInRecvBuff, T&amp; val)
{  
 memcpy(&amp;val, positionInRecvBuff, sizeof(T));
 val = ntohl(val);  
}

#endif // NETBUFFUTILCORE_H
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
NetBuffUtil.h:&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#ifndef NETBUFFUTIL_H
#define NETBUFFUTIL_H

void InsertUShort(char* positionInSendBuff, unsigned short val);
void InsertShort(char* positionInSendBuff, short val);
void InsertULong(char* positionInSendBuff, unsigned long val);
void InsertLong(char* positionInSendBuff, long val);

void ExtractUShort(char* positionInRecvBuff, unsigned short&amp; val);
void ExtractShort(char* positionInRecvBuff, short&amp; val);
void ExtractULong(char* positionInRecvBuff, unsigned long&amp; val);
void ExtractLong(char* positionInRecvBuff, long&amp; val);

#endif // NETBUFFUTIL_H
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
NetBuffUtil.cpp:&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#include "NetBuffUtilCore.h"
#include "NetBuffUtil.h"

void InsertUShort(char* positionInSendBuff, unsigned short val)
{
 InsertShortVal&lt;unsigned short&gt;(positionInSendBuff, val);
}

void InsertShort(char* positionInSendBuff, short val)
{
 InsertShortVal&lt;short&gt;(positionInSendBuff, val);
}

void InsertULong(char* positionInSendBuff, unsigned long val)
{
 InsertLongVal&lt;unsigned long&gt;(positionInSendBuff, val);
}

void InsertLong(char* positionInSendBuff, long val)
{
 InsertLongVal&lt;long&gt;(positionInSendBuff, val);
}

void ExtractUShort(char* positionInRecvBuff, unsigned short&amp; val)
{
 ExtractShortVal&lt;unsigned short&gt;(positionInRecvBuff, val);
}

void ExtractShort(char* positionInRecvBuff, short&amp; val)
{
 ExtractShortVal&lt;short&gt;(positionInRecvBuff, val);
}

void ExtractULong(char* positionInRecvBuff, unsigned long&amp; val)
{
 ExtractLongVal&lt;unsigned long&gt;(positionInRecvBuff, val);
}

void ExtractLong(char* positionInRecvBuff, long&amp; val)
{
 ExtractLongVal&lt;long&gt;(positionInRecvBuff, val);
}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
main.cpp:&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#include &lt;assert.h&gt;
#include &lt;iostream&gt;
#include "NetBuffUtil.h"
using namespace std;

void TestSendRecv_UShort_UCharBuff()
{
 std::cout &lt;&lt; "unsigned char buff" &lt;&lt; std::endl; 

 unsigned char buff[sizeof(unsigned short)] = {0};

        // this emulates actions on the sender's side
 unsigned short usSentVal = 43981; 
 std::cout &lt;&lt; "Original (unsigned short): " &lt;&lt; usSentVal &lt;&lt; std::endl; 
 InsertUShort(reinterpret_cast&lt;char*&gt;(buff), usSentVal);

        // this emulates actions on the receiver's side
 unsigned short usRecvVal = 0;
 ExtractUShort(reinterpret_cast&lt;char*&gt;(buff), usRecvVal);
 std::cout &lt;&lt; "Received val = " &lt;&lt; usRecvVal &lt;&lt; std::endl;

 std::cout &lt;&lt; std::endl; 
}

void TestSendRecv_UShort_CharBuff()
{
 std::cout &lt;&lt; "char buff" &lt;&lt; std::endl; 

 char buff[sizeof(unsigned short)] = {0};

 unsigned short usSentVal = 43981; 
 std::cout &lt;&lt; "Original (unsigned short): " &lt;&lt; usSentVal &lt;&lt; std::endl; 
 InsertUShort(buff, usSentVal);

 unsigned short usRecvVal = 0;
 ExtractUShort(buff, usRecvVal);
 std::cout &lt;&lt; "Received val = " &lt;&lt; usRecvVal &lt;&lt; std::endl; 

 std::cout &lt;&lt; std::endl; 
}

void TestSendRecv_Short_UCharBuff()
{
 std::cout &lt;&lt; "unsigned char buff" &lt;&lt; std::endl; 

 unsigned char buff[sizeof(short)] = {0};

 short usSentVal = -31234; // = 0x85fe
 std::cout &lt;&lt; "Original (short): " &lt;&lt; usSentVal &lt;&lt; std::endl;
 InsertShort(reinterpret_cast&lt;char*&gt;(buff), usSentVal);

 short usRecvVal = 0; 
 ExtractShort(reinterpret_cast&lt;char*&gt;(buff), usRecvVal);
 std::cout &lt;&lt; "Received val = " &lt;&lt; usRecvVal &lt;&lt; std::endl;

 std::cout &lt;&lt; std::endl; 
}

void TestSendRecv_Short_CharBuff()
{
 std::cout &lt;&lt; "char buff" &lt;&lt; std::endl; 

 char buff[sizeof(short)] = {0};

 short usSentVal = -31234; // = 0x85fe
 std::cout &lt;&lt; "Original (short): " &lt;&lt; usSentVal &lt;&lt; std::endl;
 InsertShort(buff, usSentVal);

 short usRecvVal = 0; 
 ExtractShort(buff, usRecvVal);
 std::cout &lt;&lt; "Received val = " &lt;&lt; usRecvVal &lt;&lt; std::endl;

 std::cout &lt;&lt; std::endl; 
}

void TestSendRecv_ULong_UCharBuff()
{
 std::cout &lt;&lt; "unsigned char buff" &lt;&lt; std::endl; 

 unsigned char buff[sizeof(unsigned long)] = {0};

 unsigned long ulSentVal = 2882343476L; // = 0xabcd1234
 std::cout &lt;&lt; "Original (unsigned long): " &lt;&lt; ulSentVal &lt;&lt; std::endl; 
 InsertULong(reinterpret_cast&lt;char*&gt;(buff), ulSentVal);

 unsigned long ulRecvVal = 0;
 ExtractULong(reinterpret_cast&lt;char*&gt;(buff), ulRecvVal);
 std::cout &lt;&lt; "Received val = " &lt;&lt; ulRecvVal &lt;&lt; std::endl; 

 std::cout &lt;&lt; std::endl; 
}

void TestSendRecv_ULong_CharBuff()
{
 std::cout &lt;&lt; "char buff" &lt;&lt; std::endl; 

 char buff[sizeof(unsigned long)] = {0};

 unsigned long ulSentVal = 2882343476L; // = 0xabcd1234
 std::cout &lt;&lt; "Original (unsigned long): " &lt;&lt; ulSentVal &lt;&lt; std::endl; 
 InsertULong(buff, ulSentVal);

 unsigned long ulRecvVal = 0;
 ExtractULong(buff, ulRecvVal);
 std::cout &lt;&lt; "Received val = " &lt;&lt; ulRecvVal &lt;&lt; std::endl; 

 std::cout &lt;&lt; std::endl; 
}

void TestSendRecv_Long_UCharBuff()
{
 std::cout &lt;&lt; "unsigned char buff" &lt;&lt; std::endl; 

 unsigned char buff[sizeof(long)] = {0};

 long lSentVal = -1107401523L; // = 0xBDFE64CD
 std::cout &lt;&lt; "Original (long): " &lt;&lt; lSentVal &lt;&lt; std::endl;
 InsertLong(reinterpret_cast&lt;char*&gt;(buff), lSentVal);

 long lRecvVal = 0; 
 ExtractLong(reinterpret_cast&lt;char*&gt;(buff), lRecvVal);
 std::cout &lt;&lt; "Received val = " &lt;&lt; lRecvVal &lt;&lt; std::endl;

 std::cout &lt;&lt; std::endl; 
}

void TestSendRecv_Long_CharBuff()
{
 std::cout &lt;&lt; "char buff" &lt;&lt; std::endl; 

 char buff[sizeof(long)] = {0};

 long lSentVal = -1107401523L; // = 0xBDFE64CD
 std::cout &lt;&lt; "Original (long): " &lt;&lt; lSentVal &lt;&lt; std::endl;
 InsertLong(buff, lSentVal);

 long lRecvVal = 0; 
 ExtractLong(buff, lRecvVal);
 std::cout &lt;&lt; "Received val = " &lt;&lt; lRecvVal &lt;&lt; std::endl;

 std::cout &lt;&lt; std::endl; 
}

void TestSendRecv()
{
 TestSendRecv_UShort_UCharBuff();
 TestSendRecv_UShort_CharBuff();
 TestSendRecv_Short_UCharBuff();
 TestSendRecv_Short_CharBuff();

 TestSendRecv_ULong_UCharBuff();
 TestSendRecv_ULong_CharBuff();
 TestSendRecv_Long_UCharBuff();
 TestSendRecv_Long_CharBuff();
}

int main(int argc, char** argv)
{
 TestSendRecv();
 return 0;
}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
Output:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="cmd_line"&gt;unsigned char buff&lt;br /&gt;
Original (unsigned short): 43981&lt;br /&gt;
Received val = 43981&lt;br /&gt;
&lt;br /&gt;
char buff&lt;br /&gt;
Original (unsigned short): 43981&lt;br /&gt;
Received val = 43981&lt;br /&gt;
&lt;br /&gt;
unsigned char buff&lt;br /&gt;
Original (short): -31234&lt;br /&gt;
Received val = -31234&lt;br /&gt;
&lt;br /&gt;
char buff&lt;br /&gt;
Original (short): -31234&lt;br /&gt;
Received val = -31234&lt;br /&gt;
&lt;br /&gt;
unsigned char buff&lt;br /&gt;
Original (unsigned long): 2882343476&lt;br /&gt;
Received val = 2882343476&lt;br /&gt;
&lt;br /&gt;
char buff&lt;br /&gt;
Original (unsigned long): 2882343476&lt;br /&gt;
Received val = 2882343476&lt;br /&gt;
&lt;br /&gt;
unsigned char buff&lt;br /&gt;
Original (long): -1107401523&lt;br /&gt;
Received val = -1107401523&lt;br /&gt;
&lt;br /&gt;
char buff&lt;br /&gt;
Original (long): -1107401523&lt;br /&gt;
Received val = -1107401523&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
To avoid dependency on Winsock library, I implemented a function which swaps bytes for a given type (well, template should be constrained to only integer types...): &lt;br /&gt;
&lt;br /&gt;
EndiannessUtil.h:&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#ifndef ENDIANNESS_UTIL
#define ENDIANNESS_UTIL

// 0x0001 
// big endian:
//   a: 00
// a+1: 01
// little endian:
//   a: 01
// a+1: 00
bool IsBigEndian()
{
 short n = 0x1; 
 return (*(char*)(&amp;n) == 0x0);
}

template &lt;typename T&gt;
T SwapBytes(T t)
{   
 for(int i = 0; i &lt; sizeof(T)/2; i++)
 {
  char temp = ((char*)(&amp;t))[i];
  ((char*)(&amp;t))[i] = ((char*)(&amp;t))[sizeof(T) - 1 - i];
  ((char*)(&amp;t))[sizeof(T) - 1 - i] = temp;  
 }

 return t;
}

template &lt;typename T&gt;
T h2n(T t)
{
 if(IsBigEndian())
  return t;

 return SwapBytes(t);
}

template &lt;typename T&gt;
T n2h(T t)
{
 if(IsBigEndian())
  return t;

 return SwapBytes(t);
}

#endif // ENDIANNESS_UTIL
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
main.cpp:&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#include &lt;assert.h&gt;
#include "EndiannessUtil.h"

void Testh2n()
{  
 assert(h2n&lt;unsigned short&gt;(0xabcd) == 0xcdab);
 assert(h2n&lt;unsigned short&gt;(0xcdab) == 0xabcd);

 assert(h2n&lt;short&gt;(0xabcd) == (short)0xcdab);
 assert(h2n&lt;short&gt;(0xcdab) == (short)0xabcd);

 assert(h2n&lt;unsigned long&gt;(0xabcd1234) == 0x3412cdab);
 assert(h2n&lt;unsigned long&gt;(0x3412cdab) == 0xabcd1234);

 assert(h2n&lt;long&gt;(0xbdfe64cd) == (long)0xcd64febd);
 assert(h2n&lt;long&gt;(0xcd64febd) == (long)0xbdfe64cd);
}

int main(int argc, char** argv)
{
 Testh2n(); // all asserts are passed
 return 0;
}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
So far, we were focused on transfer of integer types. What if message payload needs to contain strings, or, mashup of strings and integers? &lt;br /&gt;
&lt;br /&gt;
Let's say that we need to send some ASCII string and some unsigned long number. Protocol should define message payload like this: &lt;br /&gt;
&lt;br /&gt;
|L0|L1|S1|S1|S2|........|SK|N0|N1|N2|N3|&lt;br /&gt;
&lt;br /&gt;
|L0|L1| - 2 bytes for unsigned short value that defines string length (K bytes)&lt;br /&gt;
|S1|S1|S2|........|SK| - string (K bytes)&lt;br /&gt;
|N0|N1|N2|N3| - 4 bytes for unsigned long number&lt;br /&gt;
&lt;br /&gt;
Both integers should be converted to the network byte order prior to writing into sending buffer. But string does not need to be changed - that is &lt;b&gt;ASCII&lt;/b&gt; string and each character is placed in a single byte. Receiving side will first read 2 bytes of payload, extract string length (K), allocate memory for string (K bytes) and then read (copy) next K bytes from receiving buffer into the string buffer. After that, receiver will read next 4 bytes and convert them from network byte order before passing it for further processing. &lt;br /&gt;
&lt;br /&gt;
If sending &lt;a href="http://en.wikipedia.org/wiki/Unicode"&gt;&lt;b&gt;Unicode&lt;/b&gt;&lt;/a&gt; string, we need to take care about endianness again as some of its characters use two or more bytes. Our protocol will define encoding applied (e.g. UTF-8 or UTF-16) but this time sender needs to send additional information as well - its endianness. This information is contained in &lt;b&gt;&lt;a href="http://en.wikipedia.org/wiki/Byte_Order_Mark"&gt;Byte Order Mark (BOM)&lt;/a&gt;&lt;/b&gt; sequence which is prepended to our string. BOM helps Unicode decoder on the client side to decide whether to swap or not bytes for multi-byte characters.&lt;br /&gt;
&lt;br /&gt;
Links and references:&lt;br /&gt;
&lt;a href="http://beej.us/guide/bgnet/output/html/multipage/htonsman.html"&gt;htons(), htonl(), ntohs(), ntohl() (Beej's guide)&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms738557(v=vs.85).aspx"&gt;htons function (MSDN)&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms738556(v=VS.85).aspx"&gt;htonl function (MSDN)&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms740069(v=VS.85).aspx"&gt;ntohl function (MSDN)&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms740075(v=VS.85).aspx"&gt;ntohs function (MSDN)&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://linux.die.net/man/3/htons"&gt;Linux functions&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://docs.python.org/library/codecs.html#encodings-and-unicode"&gt;Encodings and Unicode (Python)&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.doughellmann.com/PyMOTW/codecs/#byte-order"&gt;Byte Order (Codecs)&lt;/a&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4912226416400969049-9184729323715091901?l=bojan-komazec.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Q_HMCcWuzKutKvTKi7Taky8mXL8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Q_HMCcWuzKutKvTKi7Taky8mXL8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Q_HMCcWuzKutKvTKi7Taky8mXL8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Q_HMCcWuzKutKvTKi7Taky8mXL8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/MyPublicNotepad/~4/DdjxWdBfsFE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://bojan-komazec.blogspot.com/feeds/9184729323715091901/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4912226416400969049&amp;postID=9184729323715091901" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/9184729323715091901?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/9184729323715091901?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyPublicNotepad/~3/DdjxWdBfsFE/host-endianness-and-data-transfer-over.html" title="Host endianness and data transfer over the network" /><author><name>Bojan Komazec</name><uri>https://profiles.google.com/117174187628268281803</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://bojan-komazec.blogspot.com/2011/12/host-endianness-and-data-transfer-over.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkIGRHY9fCp7ImA9WhRTFEk.&quot;"><id>tag:blogger.com,1999:blog-4912226416400969049.post-6039703665084002006</id><published>2011-11-04T20:59:00.000Z</published><updated>2011-11-04T21:02:05.864Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-11-04T21:02:05.864Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Windows" /><category scheme="http://www.blogger.com/atom/ns#" term="TCP/IP" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><category scheme="http://www.blogger.com/atom/ns#" term="Networking" /><title>How to get notified when network adapters' IP addresses change?</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;TCP/IP networking software requires at least one &lt;b&gt;network adapter&lt;/b&gt; bounded to &lt;b&gt;TCP/IP protocol stack&lt;/b&gt;. Each physical network card has unique &lt;b&gt;MAC address&lt;/b&gt; and &lt;b&gt;static&lt;/b&gt; or &lt;b&gt;dynamic&lt;/b&gt; &lt;b&gt;IP address&lt;/b&gt;. Static address (one or possibly more) is configured manually and dynamic address is assigned by &lt;b&gt;Dynamic Host Configuration Protocol (DHCP)&lt;/b&gt; server (if DHCP is enabled; &lt;i&gt;Obtain IP address automatically&lt;/i&gt; is ticked in &lt;i&gt;TCP/IPv4 Properties&lt;/i&gt; window). Operating system maintains table which maps IP addresses to network interfaces. Use &lt;b&gt;ipconfig&lt;/b&gt; command in command prompt window to display that table. If your adapter has DHCP enabled and you unplug/plug network cable (if using LAN adapter), disable/enable network adapter through adapter settings, issue &lt;b&gt;ipconfig /release&lt;/b&gt; or&lt;b&gt; /renew&lt;/b&gt; command, get out of/into WiFi range (if using WiFi adapter)...your adapter will loose existing or get a new IP address. NIC to IP address table will change.&lt;br /&gt;
&lt;br /&gt;
Networking applications often need to be aware when changes in this table occur. Windows API function &lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa366329(v=vs.85).aspx"&gt;&lt;b&gt;NotifyAddrChange&lt;/b&gt;&lt;/a&gt; notifies caller on this event. Here is an example of how to call it synchronously (when it's blocking):&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[

#if !defined(_MT)
#error _beginthreadex requires a multithreaded C run-time library.
#endif

#include &lt;winsock2.h&gt;
#include &lt;iphlpapi.h&gt;
#include &lt;Windows.h&gt;
#include &lt;iostream&gt;
#include &lt;sstream&gt;
#include &lt;process.h&gt;
#include &lt;iomanip&gt;

#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")

#define APP_RETURN_CODE_SUCCESS 0
#define APP_RETURN_CODE_ERROR 1

#define THREAD_RETURN_CODE_SUCCESS 0
#define THREAD_RETURN_CODE_ERROR 1

// 127.0.0.1 in network byte order
#define IP_LOCALHOST 0x0100007F

void PrintIPTable()
{ 
    PMIB_IPADDRTABLE pIPAddrTable;

 pIPAddrTable = (MIB_IPADDRTABLE*)malloc(sizeof(MIB_IPADDRTABLE));

 if(!pIPAddrTable) 
 {
  std::cout &lt;&lt; "malloc() failed" &lt;&lt; std::endl;
  return;
 }
  
 // Before calling AddIPAddress we use GetIpAddrTable to get
 // an adapter to which we can add the IP
 // Make an initial call to GetIpAddrTable to get the
 // necessary size into the dwSize variable
 
 DWORD dwSize = 0;

 if(GetIpAddrTable(pIPAddrTable, &amp;dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) 
 {
  free(pIPAddrTable);
  pIPAddrTable = (MIB_IPADDRTABLE*)malloc(dwSize);

  if(!pIPAddrTable) 
  {
   std::cout &lt;&lt; "malloc() failed" &lt;&lt; std::endl;
   return;
  }
 }
 
 DWORD dwRetVal = 0;
 LPVOID lpMsgBuf;

 // Make a second call to GetIpAddrTable to get the actual data we want
 if((dwRetVal = GetIpAddrTable(pIPAddrTable, &amp;dwSize, 0)) != NO_ERROR ) 
 { 
  std::cout &lt;&lt; "GetIpAddrTable() failed. Error code: " &lt;&lt; dwRetVal &lt;&lt; std::endl;
  
  if(FormatMessage(
   FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 
   NULL, dwRetVal, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),       
   (LPTSTR) &amp; lpMsgBuf, 0, NULL)) 
  {
   std::cout &lt;&lt; "\tError: " &lt;&lt; lpMsgBuf &lt;&lt; std::endl;
   LocalFree(lpMsgBuf);
  }

  free(pIPAddrTable);
  return;  
 }

 std::cout &lt;&lt; "\tNum Entries: " &lt;&lt; pIPAddrTable-&gt;dwNumEntries &lt;&lt; std::endl;
  
 for(int i = 0; i &lt; (int)pIPAddrTable-&gt;dwNumEntries; i++) 
 {   
  std::cout &lt;&lt; "\n\tInterface Index[" &lt;&lt; i &lt;&lt; "]:\t" &lt;&lt; pIPAddrTable-&gt;table[i].dwIndex &lt;&lt; std::endl;

  IN_ADDR IPAddr;

  IPAddr.S_un.S_addr = (u_long) pIPAddrTable-&gt;table[i].dwAddr;
  std::cout &lt;&lt; "\tIP Address[" &lt;&lt; i &lt;&lt; "]:     \t" &lt;&lt; inet_ntoa(IPAddr) &lt;&lt; std::endl;

  IPAddr.S_un.S_addr = (u_long) pIPAddrTable-&gt;table[i].dwMask;
  std::cout &lt;&lt; "\tSubnet Mask[" &lt;&lt; i &lt;&lt; "]:    \t" &lt;&lt; inet_ntoa(IPAddr) &lt;&lt; std::endl;

  IPAddr.S_un.S_addr = (u_long) pIPAddrTable-&gt;table[i].dwBCastAddr;
  std::cout &lt;&lt; "\tBroadCast[" &lt;&lt; i &lt;&lt; "]:      \t" &lt;&lt; inet_ntoa(IPAddr) &lt;&lt; "(" &lt;&lt; pIPAddrTable-&gt;table[i].dwBCastAddr &lt;&lt; ")" &lt;&lt; std::endl;
  std::cout &lt;&lt; "\tReassembly size[" &lt;&lt; i &lt;&lt; "]:\t" &lt;&lt; pIPAddrTable-&gt;table[i].dwReasmSize &lt;&lt; std::endl;

  std::cout &lt;&lt; "\tType and State[" &lt;&lt; i &lt;&lt; "]:";

  if(pIPAddrTable-&gt;table[i].wType &amp; MIB_IPADDR_PRIMARY)
   std::cout &lt;&lt; "\tPrimary IP Address";

  if(pIPAddrTable-&gt;table[i].wType &amp; MIB_IPADDR_DYNAMIC)
   std::cout &lt;&lt; "\tDynamic IP Address";

  if(pIPAddrTable-&gt;table[i].wType &amp; MIB_IPADDR_DISCONNECTED)
   std::cout &lt;&lt; "\tAddress is on disconnected interface";

  if(pIPAddrTable-&gt;table[i].wType &amp; MIB_IPADDR_DELETED)
   std::cout &lt;&lt; "\tAddress is being deleted";

  if(pIPAddrTable-&gt;table[i].wType &amp; MIB_IPADDR_TRANSIENT)
   std::cout &lt;&lt; "\tTransient address";

  std::cout &lt;&lt; std::endl;

  if(IP_LOCALHOST == pIPAddrTable-&gt;table[i].dwAddr)
  {
   std::cout &lt;&lt; "\tLOCALHOST interface" &lt;&lt; std::endl;
   // continue;
  }
    
  MIB_IFROW iInfo;
  memset(&amp;iInfo, 0, sizeof(MIB_IFROW));
  iInfo.dwIndex = pIPAddrTable-&gt;table[i].dwIndex;
  GetIfEntry(&amp;iInfo);

  std::cout &lt;&lt; "\tNetwork interface name: " &lt;&lt; iInfo.bDescr &lt;&lt; std::endl;

  std::cout &lt;&lt; "\tNetwork interface type: ";

  switch(iInfo.dwType)
  {
  case MIB_IF_TYPE_OTHER:
   std::cout &lt;&lt; "OTHER" &lt;&lt; std::endl;
   break;
  case MIB_IF_TYPE_ETHERNET:
   std::cout &lt;&lt; "ETHERNET" &lt;&lt; std::endl;
   break;
  case MIB_IF_TYPE_TOKENRING:
   std::cout &lt;&lt; "TOKENRING" &lt;&lt; std::endl;
   break;
  case MIB_IF_TYPE_FDDI:
   std::cout &lt;&lt; "FDDI" &lt;&lt; std::endl;
   break;
  case MIB_IF_TYPE_PPP:
   std::cout &lt;&lt; "PPP" &lt;&lt; std::endl;
   break;
  case MIB_IF_TYPE_LOOPBACK:
   std::cout &lt;&lt; "LOOPBACK" &lt;&lt; std::endl;
   break;
  case MIB_IF_TYPE_SLIP:
   std::cout &lt;&lt; "SLIP" &lt;&lt; std::endl;
   break;
  }

  const int unMACSegmentsCount = 6;

  if(unMACSegmentsCount == iInfo.dwPhysAddrLen)
  {      
   std::ostringstream ossMAC;
   ossMAC.fill('0');
   
   ossMAC &lt;&lt; std::setw(2) &lt;&lt; std::hex &lt;&lt; static_cast&lt;unsigned int&gt;(iInfo.bPhysAddr[0]);

   for(int i = 1; i &lt; unMACSegmentsCount; i++)
   {
    ossMAC &lt;&lt; '-' &lt;&lt; std::setw(2) &lt;&lt; std::hex &lt;&lt; static_cast&lt;unsigned int&gt;(iInfo.bPhysAddr[i]);
   }
    
   std::cout &lt;&lt; "\tMAC Address:            " &lt;&lt; ossMAC.str() &lt;&lt; std::endl;   
  }  

  std::cout &lt;&lt; std::endl;
 } 

 if (pIPAddrTable) 
 {
  free(pIPAddrTable);
  pIPAddrTable = 0;
 }
}

unsigned __stdcall thfn(void* args)
{
 HANDLE hTerminateEvent = *(HANDLE*)args;
 BOOL bTerminate = FALSE;
 
 OVERLAPPED overlap;
 overlap.hEvent = WSACreateEvent();

 if(overlap.hEvent == WSA_INVALID_EVENT)
 {
  std::cout &lt;&lt; "WSACreateEvent() failed. Error code: " &lt;&lt; WSAGetLastError() &lt;&lt; std::endl;
  return THREAD_RETURN_CODE_ERROR;
 }

 while(!bTerminate)
 { 
  
  HANDLE h = 0;

  // call NotifyAddrChange in synchronous mode
  DWORD dwRetVal = NotifyAddrChange(&amp;h, &amp;overlap);

  if(dwRetVal != ERROR_IO_PENDING)
  {
   std::cout &lt;&lt; "NotifyAddrChange() failed. Error code: " &lt;&lt; WSAGetLastError() &lt;&lt; std::endl;
   break;
  }

  HANDLE waitObjects[2] = {hTerminateEvent, overlap.hEvent};

  std::cout &lt;&lt; "\nWaiting for IP Table change or termination request..." &lt;&lt; std::endl;

  dwRetVal = WaitForMultipleObjects(2, waitObjects, FALSE, INFINITE);

  switch(dwRetVal)
  {
  case WAIT_OBJECT_0:
   std::cout &lt;&lt; "WaitForSingleObject(waitObjects) returned WAIT_OBJECT_0 (hTerminateEvent is signaled)" &lt;&lt; std::endl;
   bTerminate = TRUE;
   break;
  case WAIT_OBJECT_0 + 1:
   std::cout &lt;&lt; "WaitForSingleObject(waitObjects) returned WAIT_OBJECT_0 + 1 (overlap.hEvent is signaled)" &lt;&lt; std::endl;   
   
   if(!WSAResetEvent(overlap.hEvent))
   {
    std::cout &lt;&lt; "WSAResetEvent() failed. Error code: " &lt;&lt; WSAGetLastError() &lt;&lt; std::endl;
    bTerminate = TRUE;
    break;
   }

   PrintIPTable();
   break;
  case WAIT_FAILED:
   std::cout &lt;&lt; "WaitForSingleObject(waitObjects) returned WAIT_FAILED (function failed)" &lt;&lt; std::endl;
   bTerminate = TRUE;
   break;
  }  
 }
 
 if(!WSACloseEvent(overlap.hEvent))
 {
  std::cout &lt;&lt; "WSACloseEvent() failed. Error code: " &lt;&lt; WSAGetLastError() &lt;&lt; std::endl;
  return THREAD_RETURN_CODE_ERROR;
 }

 return THREAD_RETURN_CODE_SUCCESS;
}

void WaitUserInput()
{
 std::cin.clear(); 
 std::cin.ignore(1, '\n');
}

// NOTE: std::cout is shared between two threads and is not thread safe!
int main(int argc, char* argv[])
{
// std::cout &lt;&lt; "main()" &lt;&lt; std::endl;

 HANDLE hTerminateEvent = CreateEvent(0, TRUE, FALSE, 0);

 if(!hTerminateEvent)
 {
  std::cout &lt;&lt; "CreateEvent() failed. Error code: " &lt;&lt; GetLastError() &lt;&lt; std::endl;
  return APP_RETURN_CODE_ERROR;
 }

 unsigned unThreadID = 0;
 HANDLE hThread = 0;

// std::cout &lt;&lt; "Creating thread..." &lt;&lt; std::endl;
 hThread = (HANDLE) _beginthreadex(0, 0, thfn, &amp;hTerminateEvent, 0, &amp;unThreadID);

 if(!hThread)
 {
  std::cout &lt;&lt; "_beginthreadex() failed. Error code: " &lt;&lt; errno &lt;&lt; std::endl;
  return APP_RETURN_CODE_ERROR;
 }

 // (not reliable way to) make sure child thread has started before main thread continues
 Sleep(1000);

// std::cout &lt;&lt; "Created thread with ID: " &lt;&lt; unThreadID &lt;&lt; std::endl;

 std::cout &lt;&lt; "Press ENTER to terminate listening for changes in IP address table..." &lt;&lt; std::endl;
 WaitUserInput();

 SetEvent(hTerminateEvent);

 // wait for thread to terminate
 DWORD dwRetVal = WaitForSingleObject(hThread, INFINITE);

 switch(dwRetVal)
 {
 case WAIT_OBJECT_0:
  std::cout &lt;&lt; "WaitForSingleObject(hThread) returned WAIT_OBJECT_0 (event is signaled)" &lt;&lt; std::endl;
  break;
 case WAIT_TIMEOUT:
  std::cout &lt;&lt; "WaitForSingleObject(hThread) returned WAIT_TIMEOUT (timeout elapsed; event is nonsignaled)" &lt;&lt; std::endl;
  break;
 case WAIT_FAILED:
  std::cout &lt;&lt; "WaitForSingleObject(hThread) returned WAIT_FAILED (function failed)" &lt;&lt; std::endl;
  break;
 }

 if(!CloseHandle(hThread))
 {
  std::cout &lt;&lt; "CloseHandle() failed. Error code: " &lt;&lt; GetLastError() &lt;&lt; std::endl;
  return APP_RETURN_CODE_ERROR;
 }

 std::cout &lt;&lt; "Press ENTER to exit..." &lt;&lt; std::endl;
 WaitUserInput();

// std::cout &lt;&lt; "~main()" &lt;&lt; std::endl;
 return APP_RETURN_CODE_SUCCESS;
}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
This is the output if we unplug network cable and then plug it back again:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="cmd_line"&gt;&lt;br /&gt;
Waiting for IP Table change or termination request...&lt;br /&gt;
Press ENTER to terminate listening for changes in IP address table...&lt;br /&gt;
WaitForSingleObject(waitObjects) returned WAIT_OBJECT_0 + 1 (overlap.hEvent is s&lt;br /&gt;
ignaled)&lt;br /&gt;
Num Entries: 2&lt;br /&gt;
&lt;br /&gt;
Interface Index[0]:     17&lt;br /&gt;
IP Address[0]:          192.168.56.1&lt;br /&gt;
Subnet Mask[0]:         255.255.255.0&lt;br /&gt;
BroadCast[0]:           1.0.0.0(1)&lt;br /&gt;
Reassembly size[0]:     65535&lt;br /&gt;
Type and State[0]:      Primary IP Address&lt;br /&gt;
Network interface name: VirtualBox Host-Only Ethernet Adapter&lt;br /&gt;
Network interface type: ETHERNET&lt;br /&gt;
MAC Address:            08-00-27-00-68-56&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Interface Index[1]:     1&lt;br /&gt;
IP Address[1]:          127.0.0.1&lt;br /&gt;
Subnet Mask[1]:         255.0.0.0&lt;br /&gt;
BroadCast[1]:           1.0.0.0(1)&lt;br /&gt;
Reassembly size[1]:     65535&lt;br /&gt;
Type and State[1]:      Primary IP Address&lt;br /&gt;
LOCALHOST interface&lt;br /&gt;
Network interface name: Software Loopback Interface 1&lt;br /&gt;
Network interface type: LOOPBACK&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Waiting for IP Table change or termination request...&lt;br /&gt;
WaitForSingleObject(waitObjects) returned WAIT_OBJECT_0 + 1 (overlap.hEvent is s&lt;br /&gt;
ignaled)&lt;br /&gt;
Num Entries: 3&lt;br /&gt;
&lt;br /&gt;
Interface Index[0]:     10&lt;br /&gt;
IP Address[0]:          192.168.253.122&lt;br /&gt;
Subnet Mask[0]:         255.255.255.0&lt;br /&gt;
BroadCast[0]:           1.0.0.0(1)&lt;br /&gt;
Reassembly size[0]:     65535&lt;br /&gt;
Type and State[0]:      Primary IP Address      Dynamic IP Address&lt;br /&gt;
Network interface name: Intel(R) 82566DC Gigabit Network Connection&lt;br /&gt;
Network interface type: ETHERNET&lt;br /&gt;
MAC Address:            00-19-d1-1b-e0-88&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Interface Index[1]:     17&lt;br /&gt;
IP Address[1]:          192.168.56.1&lt;br /&gt;
Subnet Mask[1]:         255.255.255.0&lt;br /&gt;
BroadCast[1]:           1.0.0.0(1)&lt;br /&gt;
Reassembly size[1]:     65535&lt;br /&gt;
Type and State[1]:      Primary IP Address&lt;br /&gt;
Network interface name: VirtualBox Host-Only Ethernet Adapter&lt;br /&gt;
Network interface type: ETHERNET&lt;br /&gt;
MAC Address:            08-00-27-00-68-56&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Interface Index[2]:     1&lt;br /&gt;
IP Address[2]:          127.0.0.1&lt;br /&gt;
Subnet Mask[2]:         255.0.0.0&lt;br /&gt;
BroadCast[2]:           1.0.0.0(1)&lt;br /&gt;
Reassembly size[2]:     65535&lt;br /&gt;
Type and State[2]:      Primary IP Address&lt;br /&gt;
LOCALHOST interface&lt;br /&gt;
Network interface name: Software Loopback Interface 1&lt;br /&gt;
Network interface type: LOOPBACK&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Waiting for IP Table change or termination request...&lt;br /&gt;
&lt;br /&gt;
WaitForSingleObject(waitObjects) returned WAIT_OBJECT_0 (hTerminateEvent is sign&lt;br /&gt;
aled)&lt;br /&gt;
WaitForSingleObject(hThread) returned WAIT_OBJECT_0 (event is signaled)&lt;br /&gt;
Press ENTER to exit...&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4912226416400969049-6039703665084002006?l=bojan-komazec.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/0N-kXrVppUp6FZDoNjZx_KhCEks/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/0N-kXrVppUp6FZDoNjZx_KhCEks/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/0N-kXrVppUp6FZDoNjZx_KhCEks/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/0N-kXrVppUp6FZDoNjZx_KhCEks/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/MyPublicNotepad/~4/wy7CJxJAjJg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://bojan-komazec.blogspot.com/feeds/6039703665084002006/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4912226416400969049&amp;postID=6039703665084002006" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/6039703665084002006?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/6039703665084002006?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyPublicNotepad/~3/wy7CJxJAjJg/how-to-get-notified-when-network.html" title="How to get notified when network adapters' IP addresses change?" /><author><name>Bojan Komazec</name><uri>https://profiles.google.com/117174187628268281803</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://bojan-komazec.blogspot.com/2011/11/how-to-get-notified-when-network.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A04MQHoyfCp7ImA9WhdaF08.&quot;"><id>tag:blogger.com,1999:blog-4912226416400969049.post-6842738240568239607</id><published>2011-10-27T16:39:00.001+01:00</published><updated>2011-10-27T16:39:41.494+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-27T16:39:41.494+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Visual Studio" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><title>How to include stdafx.h conditionally?</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
Don't try it as that's not possible!&lt;br /&gt;
&lt;br /&gt;
If you try to put &lt;b&gt;#include "stdafx.h"&lt;/b&gt; between &lt;b&gt;#ifdef&lt;/b&gt; and &lt;b&gt;#endif&lt;/b&gt;, you'll end up with &lt;i&gt;error C1020: unexpected #endif.&lt;/i&gt; You need to include &lt;b&gt;stdafx.h&lt;/b&gt; at the beginning of any source file in your project, apart from those files for which using precompiled headers is turned off.&lt;br /&gt;
&lt;br /&gt;
There is one situation where this feature - setting using precompiled headers at the file level - comes very handy. Let's say we have some code file which does not include &lt;b&gt;stdafx.h&lt;/b&gt; and we need to share it between project which uses precompiled headers - P1, and project which doesn't - P2. If we add that file to P1, this project won't compile &amp;nbsp;- compiler will complain with &lt;i&gt;fatal error C1010: unexpected end of file while looking for precompiled header&lt;/i&gt;.&amp;nbsp;We cannot include &lt;b&gt;stdafx.h&lt;/b&gt; at the beginning of that file either as then P2 won't compile - it does not have &lt;b&gt;stdafx.h&lt;/b&gt;.&amp;nbsp;The only solution is to turn off using precompiled headers for that particular file.&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4912226416400969049-6842738240568239607?l=bojan-komazec.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/5I6U-VbS9CVLUnaSBWfFOTqXLJY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5I6U-VbS9CVLUnaSBWfFOTqXLJY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/5I6U-VbS9CVLUnaSBWfFOTqXLJY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/5I6U-VbS9CVLUnaSBWfFOTqXLJY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/MyPublicNotepad/~4/XWwvinByPmw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://bojan-komazec.blogspot.com/feeds/6842738240568239607/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4912226416400969049&amp;postID=6842738240568239607" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/6842738240568239607?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/6842738240568239607?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyPublicNotepad/~3/XWwvinByPmw/how-to-include-stdafxh-conditionally.html" title="How to include stdafx.h conditionally?" /><author><name>Bojan Komazec</name><uri>https://profiles.google.com/117174187628268281803</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://bojan-komazec.blogspot.com/2011/10/how-to-include-stdafxh-conditionally.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUECQXs6fyp7ImA9WhRXEEg.&quot;"><id>tag:blogger.com,1999:blog-4912226416400969049.post-4967440580998849470</id><published>2011-10-25T15:57:00.002+01:00</published><updated>2011-12-16T17:47:40.517Z</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-16T17:47:40.517Z</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="C" /><category scheme="http://www.blogger.com/atom/ns#" term="Design Patterns" /><title>Finite State Machine in C</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Finite State Machine is a way of modelling behaviour of some entity that can have a (finite) set of states. Depending on the received event, entity performs some action and changes its state (or remains in the current one).&lt;br /&gt;
&lt;br /&gt;
Let's say we want to model a behaviour of some simple car. I call it "simple" as it has only ignition switch, accelerator and brake. Driver can turn it on, then accelerate, brake and, at the end of the journey, turn it off. If not careful, driver can break the car - if tries to turn it on (again) while driving. Driver's actions are events - inputs of our model. Car can be turned off, idling, moving or broken - and this is a set of our car's states. So, car is in some state, it reacts on driver's command (event), performs some action and goes into the next state.&lt;br /&gt;
&lt;br /&gt;
We have a finite set of states and events and can draw a diagram which precisely define state transitions (state transition diagram):&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.flickr.com/photos/25233492@N05/6279643701/" title="FSM_CarExample_1 by Bojan Komazec, on Flickr"&gt;&lt;img src="http://farm7.static.flickr.com/6050/6279643701_539460fc35_z.jpg" width="640" height="238" alt="FSM_CarExample_1"&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Now, how to implement this model and show how this state machine changes states after receiving events? &lt;br /&gt;
&lt;br /&gt;
Each state can be represented as unique number - its code, or ID. The similar thing is with events. As we have finite number of both states and events, we can use enum type to represent them: one variable will be of &lt;b&gt;enum STATE&lt;/b&gt; type and contain the ID of the current state and another variable will be of type &lt;b&gt;enum EVENT&lt;/b&gt; and will contain the most recent event this system received. Initially, our car is turned off so the state variable will be set to STATE_TURNED_OFF. After this simple initialization we just need to wait for events and handle them in accordance to the given transition diagram. Events can be obtained from a keyboard or some other source and they are usually kept in a queue as sometimes a new event can be received before processing of the previous one is finished. In this example, in order to keep things simple, I'm gonna assume that processing is fast enough and will just create a predefined set of events and put them in an array.&lt;br /&gt;
&lt;br /&gt;
As we have repetitive action - receiving and handling events - we'll put it in a loop. If our events source is keyboard and we don't know how many events will user issue, we can use while-loop and CTRL-C as a loop termination command. In this example, we have an array of events which is of predefined (known in advance) size so we can use for-loop. Inside this loop, we need to place event processing code for each event, received in each state. This means we will have switch-statement inside another switch-statement. So, here's the code:&lt;br /&gt;
&lt;br /&gt;
main.c:&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[

#include &lt;stdio.h&gt;

#define EVENTS_COUNT 4
#define STATES_COUNT 4
#define EVENT_QUEUE_SIZE 4

typedef enum STATE
{ 
 STATE_INVALID,
 STATE_TURNED_OFF,
 STATE_IDLE, 
 STATE_MOVING
} STATE;

typedef enum EVENT
{
 EVENT_IGNITE,
 EVENT_ACCELERATE, 
 EVENT_BRAKE,
 EVENT_TURN_OFF
} EVENT;


void ignited()
{
 printf("Whoooa! I'm turned on!\n"); 
}

void do_nothing()
{
 printf("Don't bother!\n");
}

void complain()
{
 printf("This hurts!\n");
}

void accelerating()
{
 printf("Yipee! I'm accelerating!\n"); 
}

void say_goodbye()
{
 printf("That was probably enough...\n");
}

void braking()
{
 printf("Whoops! Was I too fast?\n");
}

int main()
{
 STATE state = STATE_TURNED_OFF;  
 EVENT eventQueue[EVENT_QUEUE_SIZE] = {EVENT_IGNITE, EVENT_ACCELERATE, EVENT_BRAKE, EVENT_TURN_OFF}; 
 int eventIndex = 0;

 for(; eventIndex &lt; EVENTS_COUNT; eventIndex++)
 {
  EVENT evt = eventQueue[eventIndex];
  
  switch(evt)
  {
  case EVENT_IGNITE:
   {
    switch(state)
    {
    case STATE_INVALID:
     {
      break;
     }
    case STATE_TURNED_OFF:
     {
      ignited();
      state = STATE_IDLE;
      break;
     }
    case STATE_IDLE:
     {
      complain();
      state = STATE_INVALID;
      break;
     }
    case STATE_MOVING: 
     {
      complain();
      state = STATE_INVALID;
      break;
     }
    }

    break;
   }
  case EVENT_ACCELERATE:
   {
    switch(state)
    {
    case STATE_INVALID:
     {
      break;
     }
    case STATE_TURNED_OFF:
     {
      do_nothing();
      break;
     }
    case STATE_IDLE:
     {
      accelerating();
      state = STATE_MOVING;
      break;
     }
    case STATE_MOVING: 
     {
      accelerating();
      break;
     }
    }

    break;
   }
  case EVENT_BRAKE:
   {
    switch(state)
    {
    case STATE_INVALID:
     {
      break;
     }
    case STATE_TURNED_OFF:
     {
      do_nothing();
      break;
     }
    case STATE_IDLE:
     {
      do_nothing();
      break;
     }
    case STATE_MOVING: 
     {
      braking();
      state = STATE_IDLE;
      break;
     }
    }

    break;
   }
  case EVENT_TURN_OFF:
   {
    switch(state)
    {
    case STATE_INVALID:
     {
      break;
     }
    case STATE_TURNED_OFF:
     {
      do_nothing();
      break;
     }
    case STATE_IDLE:
     {
      say_goodbye();
      state = STATE_TURNED_OFF;
      break;
     }
    case STATE_MOVING: 
     { 
      complain();
      state = STATE_INVALID;
      break;
     }
    }

    break;
   }
  }
 }

 return 0;
}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
Output:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="cmd_line"&gt;Whoooa! I'm turned on!&lt;br /&gt;
Yipee! I'm accelerating!&lt;br /&gt;
Whoops! Was I too fast?&lt;br /&gt;
That was probably enough...&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
Having a switch inside a switch looks a bit complex and difficult to maintain. If we add a new state, we need to add a new case-branch for each event. In the code above it would mean we need to make changes at 4 different places in the code! Not good!&lt;br /&gt;
&lt;br /&gt;
A solution for this is a &lt;b&gt;state transition table&lt;/b&gt;. It is basically a table in which each state has its column and each event has its row. Table elements are pairs action/next-state - let's put them in some structure called TRANSITION. If transition table is called trans_tbl its element, trans_tbl[evt][state] is of type TRANSITION and action is a function called during transition and next-state is the state our model goes into for the current event. Code tells this better:&lt;br /&gt;
&lt;br /&gt;
main.c:&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[
#include &lt;stdio.h&gt;

#define EVENTS_COUNT 4
#define STATES_COUNT 4
#define EVENT_QUEUE_SIZE 4

typedef enum STATE
{ 
 STATE_INVALID,
 STATE_TURNED_OFF,
 STATE_IDLE, 
 STATE_MOVING
} STATE;

typedef enum EVENT
{
 EVENT_IGNITE,
 EVENT_ACCELERATE, 
 EVENT_BRAKE,
 EVENT_TURN_OFF
} EVENT;

typedef void (*TPF)();

typedef struct TRANSITION
{
 STATE next_state;
 TPF action;
} TRANSITION;

void ignited()
{
 printf("Whoooa! I'm turned on!\n"); 
}

void do_nothing()
{
 printf("Don't bother!\n");
}

void complain()
{
 printf("This hurts!\n");
}

void accelerating()
{
 printf("Yipee! I'm accelerating!\n"); 
}

void say_goodbye()
{
 printf("That was probably enough...\n");
}

void braking()
{
 printf("Whoops! Was I too fast?\n");
}

TRANSITION trans_tbl[EVENTS_COUNT][STATES_COUNT] = 
{                    /*STATE_INVALID*/    /*STATE_TURNED_OFF*/            /*STATE_IDLE*/                   /*STATE_MOVING*/
/*EVENT_IGNITE*/     {{STATE_INVALID, 0}, {STATE_IDLE, ignited},          {STATE_INVALID, complain},       {STATE_INVALID, complain}}, 
/*EVENT_ACCELERATE*/ {{STATE_INVALID, 0}, {STATE_TURNED_OFF, do_nothing}, {STATE_MOVING, accelerating},    {STATE_MOVING, accelerating}},      
/*EVENT_BRAKE*/      {{STATE_INVALID, 0}, {STATE_TURNED_OFF, do_nothing}, {STATE_IDLE, do_nothing},        {STATE_IDLE, braking}},
/*EVENT_TURN_OFF*/   {{STATE_INVALID, 0}, {STATE_TURNED_OFF, do_nothing}, {STATE_TURNED_OFF, say_goodbye}, {STATE_INVALID, complain}} 
};


int main()
{
 STATE state = STATE_TURNED_OFF;  
 EVENT event_queue[EVENT_QUEUE_SIZE] = {EVENT_IGNITE, EVENT_ACCELERATE, EVENT_BRAKE, EVENT_TURN_OFF}; 
 int event_index = 0;

 for(; event_index &lt; EVENTS_COUNT; event_index++)
 {
  EVENT evt = event_queue[event_index ];

  trans_tbl[evt][state].action();
  state = trans_tbl[evt][state].next_state;
 }

 return 0;
}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
Output is the same:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="cmd_line"&gt;Whoooa! I'm turned on!&lt;br /&gt;
Yipee! I'm accelerating!&lt;br /&gt;
Whoops! Was I too fast?&lt;br /&gt;
That was probably enough...&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
The code has shrunk and become easier to understand and maintain: if we want to add a new event or a state, we just need to change transition table (trans_tbl) - we don't need to touch the code in a loop!&lt;br /&gt;
&lt;br /&gt;
My article &lt;a href="http://bojan-komazec.blogspot.com/2011/12/finite-state-machine-in-c.html"&gt;"Finite State Machine in C++"&lt;/a&gt; shows how to use OOP and State design pattern in order to implement FSM described here.&lt;br /&gt;
&lt;br /&gt;
Links and references:&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/Finite-state_machine"&gt;Finite-state machine (Wikipedia)&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.objectmentor.com/resources/articles/umlfsm.pdf"&gt;UML Tutorial:  Finite State Machines&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4912226416400969049-4967440580998849470?l=bojan-komazec.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/k01bbZjRR5qDP2-9RX32Ybd9zH8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/k01bbZjRR5qDP2-9RX32Ybd9zH8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/k01bbZjRR5qDP2-9RX32Ybd9zH8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/k01bbZjRR5qDP2-9RX32Ybd9zH8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/MyPublicNotepad/~4/il1J0LluuVk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://bojan-komazec.blogspot.com/feeds/4967440580998849470/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4912226416400969049&amp;postID=4967440580998849470" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/4967440580998849470?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/4967440580998849470?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyPublicNotepad/~3/il1J0LluuVk/finite-state-machine-in-c.html" title="Finite State Machine in C" /><author><name>Bojan Komazec</name><uri>https://profiles.google.com/117174187628268281803</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://farm7.static.flickr.com/6050/6279643701_539460fc35_t.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://bojan-komazec.blogspot.com/2011/10/finite-state-machine-in-c.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkEAQnYyeSp7ImA9WhdbFUQ.&quot;"><id>tag:blogger.com,1999:blog-4912226416400969049.post-1737247028752134456</id><published>2011-10-14T14:15:00.000+01:00</published><updated>2011-10-14T14:24:03.891+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-14T14:24:03.891+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Axis2C" /><category scheme="http://www.blogger.com/atom/ns#" term="logging" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><category scheme="http://www.blogger.com/atom/ns#" term="Guththila" /><title>Reading XML with Guththila</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
Guththila is Apache XML parser for&amp;nbsp;Axis2/C.&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
I've been playing with Guththila recently and just want to share code which demonstrates how to use Guththila in a standalone application,&amp;nbsp;GuththilaTest. It will read data from the following XML file:&lt;br /&gt;
&lt;br /&gt;
books.xml:&lt;br /&gt;
&lt;div class="my_code"&gt;
&lt;br /&gt;
&amp;lt;?xml version="1.0" ?&amp;gt;&lt;br /&gt;
&amp;lt;books&amp;gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&amp;lt;Genre Name="Biography"&amp;gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;&amp;lt;Author Name="Michael Moore"&amp;gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;&amp;lt;Book Name="Here Comes Trouble" ISBN="9780713997019" PublishingDate="13-Sep-2011"/&amp;gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;&amp;lt;/Author&amp;gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;&amp;lt;Author Name="Alan Sugar"&amp;gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;&amp;lt;Book Name="Way I See it" ISBN="9780230760899" PublishingDate="29-Sep-2011"/&amp;gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;&amp;lt;/Author&amp;gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&amp;lt;/Genre&amp;gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&amp;lt;Genre Name="Fiction"&amp;gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;&amp;lt;Author Name="Ivo Andric"&amp;gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;&amp;lt;Book Name="Bridge Over the Drina" ISBN="9781860460586" PublishingDate="05-Apr-1994"/&amp;gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;&amp;lt;/Author&amp;gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;&amp;lt;Author Name="Fyodor Dostoyevsky"&amp;gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;&amp;lt;Book Name="Crime and Punishment" ISBN="9780955816949" PublishingDate="30-Oct-2008"/&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&amp;lt;Book Name="Brothers Karamazov" ISBN="9780140449242" PublishingDate="27-Feb-2003"/&amp;gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;&amp;lt;/Author&amp;gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&amp;lt;/Genre&amp;gt;&lt;br /&gt;
&amp;lt;/books&amp;gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
We need to download Axis2/C binary package (or its source and build binaries ourselves) as Guththila requires&amp;nbsp;axutil.dll and guththila.dll&amp;nbsp;in a runtime and application that uses Guththila must be linked against its static libraries axutil.lib and guththila.lib.&lt;br /&gt;
&lt;br /&gt;
Axis2/C manual suggest placing Axis2/C package at some location your disk (e.g. c:\axis2c) and setting environment variable AXIS2C_HOME to that path, plus adding %AXIS2C_HOME%/lib to Path environment variable so any application can find Axis2C libraries.&lt;br /&gt;
&lt;br /&gt;
In this example, I will use minimalistic approach, putting all necessary libraries (axutil.dll,&amp;nbsp;guththila.dll) in application's directory.&lt;br /&gt;
&lt;br /&gt;
If path to necessary Axis2C DLLs is not in Path environment variable and if necessary DLLs are not in the application's directory, following message appears if you try to run the app:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="black_border"&gt;
---------------------------&lt;br /&gt;
GuththilaTest.exe - System Error&lt;br /&gt;
---------------------------&lt;br /&gt;
The program can't start because axutil.dll is missing from your computer. Try reinstalling the program to fix this problem. &lt;br /&gt;
---------------------------&lt;br /&gt;
OK   &lt;br /&gt;
---------------------------&lt;/div&gt;
&lt;br /&gt;
We need to create environment variable, and we want to have log file as well so we need to call axutil_env_create_all() function.&lt;br /&gt;
&lt;br /&gt;
This algorithm explains the logic of the Axis2/C log file creation:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="file_hierarchy"&gt;
pass log file string to axutil_env_create_all() as an argument&lt;br /&gt;
&lt;br /&gt;
axutil_env_create_all() forwards that string to axutil_log_create()&lt;br /&gt;
&lt;br /&gt;
if (string is full path to log file, including its name)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;axutil_log_create() creates log file at the proved path&lt;br /&gt;
else (string is just log file name)&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;axutil_log_create() tries to read path from AXIS2C_HOME environment variable&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;if AXIS2C_HOME path obtained&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;axutil_log_create() creates log file at AXIS2C_HOME/logs path&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;else&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;axutil_log_create() creates log file in the current directory   &lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
I don't want to change environment variables so just place axutil.dll and guththila.dll (together with books.xml) in the same directory with GuththilaTest.exe. As I don't set AXIS2C_HOME environment variable, Axis creates log file in the same directory.&lt;br /&gt;
&lt;br /&gt;
So here is the code. ReadXML(...) outputs formatted content of the XML file to the standard output. GetBookInfo(...) performs search for a particular node. Each parsing session (going through XML) requires (re)initialized parser. guth_init(...) is therefore called before and guth_clean() after each of these two functions. GetStrLen(), CopyStrRealloc() and PrintSpaces() are some helper functions.&lt;br /&gt;
&lt;br /&gt;
main.c:&lt;br /&gt;
&lt;br /&gt;
&lt;script class="brush: cpp" type="syntaxhighlighter"&gt;
&lt;![CDATA[

// Apache Guththila XML parser demo
//
// Guththila-based Axis2/C build MUST be used for x64 builds as there is no x64 build for libxml2.
// Guththila CAN be used for x32 builds =&gt; libxml2.dll, iconv.dll and zlib1.dll are not needed
//
// Additional include paths: 
//    ..\axis2c\include;..\Axis2C\guththila\include
// Additional dependencies:
//    axutil.lib, guththila.lib
// Additional library paths:
//    ...\3rdParty\Axis2C\lib

#include &lt;axutil_env.h&gt;
#include &lt;guththila.h&gt;
#include &lt;guththila_defines.h&gt;
#include &lt;string.h&gt;

#define bool int
#define true 1
#define false 0

typedef struct book_info_t
{
 char* pszGenre;
 char* pszAuthor;
 char* pszName;
 char* pszISBN;
 char* pszPublishingDate; 
} book_info;

unsigned int GetStrLen(const char* str)
{ 
 unsigned int nIndex = 0;

 if(str)  
 {
  while(str[nIndex] != '\0')
  {
   nIndex++;
  }
 }

 return nIndex;
}

/// Copies string to a destination buffer.
/// Previous content of destination buffer is deleted and memory is reallocated.
/// @param dest_addr is an address of the destination string
/// @param str - string to be copied
/// @return unsigned int - error code (0 in case of success; !=0 otherwise)
unsigned int CopyStrRealloc(char** dest_addr, const char* str)
{
 unsigned int nStrLen = 0;
 errno_t err_code = 0;

 if(!str)
  return 1;

 if(!dest_addr)
  return 2;

 if(*dest_addr)
 {
  free((void*)(*dest_addr));
 }

 nStrLen = GetStrLen(str);

 *dest_addr = (char*)malloc(nStrLen + 1);

 if(!(*dest_addr))
  return 3;

 err_code = strncpy_s(*dest_addr, nStrLen + 1, str, nStrLen);

 if(err_code)
 {   
  free((void*)(*dest_addr));
  *dest_addr = NULL;
  return err_code;
 }

 (*dest_addr)[nStrLen] = '\0';

 return 0;
}

void PrintSpaces(int nCount)
{
 int n = 0;
 for(; n &lt; nCount; n++)
  printf("%s", " ");
}

void DebugParser(guththila_t* parser, axutil_env_t* env)
{
 AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "DebugParser()\n\
\tguththila_event=%d\n\
\tlast_start=%d\n\
\tname=%d\n\
\tnext=%d\n\
\tstatus=%d\n",
parser-&gt;guththila_event,
parser-&gt;last_start,
parser-&gt;name,
parser-&gt;next,
parser-&gt;status);
}

void DebugReader(guththila_reader_t* reader, axutil_env_t* env)
{
 AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "DebugReader()\n\
\tbuff_size=%d\n\
\ttype=%d",
reader-&gt;buff_size,
reader-&gt;type);
}

int guth_init(guththila_reader_t** reader, guththila_t** parser, axutil_env_t* env, const char* pszXMLFilePath)
{
 *reader = guththila_reader_create_for_file((char*)pszXMLFilePath, env);  

 if(!*reader)
 {
  AXIS2_LOG_ERROR(env-&gt;log, AXIS2_LOG_SI, "guththila_reader_create_for_file() failed");
  return 1;
 }

 AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "reader created");

 DebugReader(*reader, env);

 *parser = (guththila_t*) AXIS2_MALLOC(env-&gt;allocator, sizeof(guththila_t));

 if(!*parser)
 {
  AXIS2_LOG_ERROR(env-&gt;log, AXIS2_LOG_SI, "parser is NULL");
  return 2;
 }

 // this function is used instead the old one (guththila_create)
 if(guththila_init(*parser, *reader, env) == GUTHTHILA_FAILURE)
 {
  AXIS2_LOG_ERROR(env-&gt;log, AXIS2_LOG_SI, "guththila_init() failed");
  return 3;
 } 

 AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "parser created");

 DebugParser(*parser, env);
 DebugReader(*reader, env);

 return 0;
}

void guth_clean(guththila_reader_t** reader, guththila_t** parser, axutil_env_t* env)
{
 if(*reader) 
 {
  guththila_reader_free(*reader, env);
  AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "guththila_reader_free() ok");
 }

 if(*parser)
 {
  // guththila_un_init deallocates memory for parser
  guththila_un_init(*parser, env);  
  AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "guththila_un_init() ok");  
 }
}

void ReadXML(guththila_t* parser, axutil_env_t* env)
{
 int evt = 0; 

 while((evt = guththila_next(parser, env)) != -1)
 {    
  AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "Number of elements in guththila stack: %d", parser-&gt;elem.top);

  switch(evt)
  {
   case GUTHTHILA_START_DOCUMENT:
    { 
     AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "GUTHTHILA_START_DOCUMENT");
    }
    break;
   case GUTHTHILA_START_ELEMENT:
   case GUTHTHILA_EMPTY_ELEMENT:
    {
     char* pszName = 0;
     char* pszPrefix = 0;
     int nCountAttributes = 0;

     if(evt == GUTHTHILA_START_ELEMENT)
     {
      AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "GUTHTHILA_START_ELEMENT");      
     }
     else
     {
      // empty element is one that does not have child elements; it can have attributes though
      AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "GUTHTHILA_EMPTY_ELEMENT");
     }
     
     PrintSpaces(parser-&gt;elem.top);
     printf("&lt;");

     pszPrefix = guththila_get_prefix(parser, env);

     if(pszPrefix)
     {
      AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "Prefix: \"%s\"", pszPrefix);
      AXIS2_FREE(env-&gt;allocator, pszPrefix);
      pszPrefix = 0;
     }
     
     // guththila_get_name returns 0 if current node (token) does not have name     
     pszName = guththila_get_name(parser, env);

     if(!pszName)
      break;
     
     AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "Name: \"%s\"", pszName);          
     printf("%s", pszName);

     AXIS2_FREE(env-&gt;allocator, pszName);
     pszName = 0;

     nCountAttributes = guththila_get_attribute_count(parser, env);
     AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "Number of attributes: %d", nCountAttributes);

     if((evt == GUTHTHILA_START_ELEMENT) &amp;&amp; (nCountAttributes == 0))
     {
      printf("&gt;\n");
      break;
     }

     for(; nCountAttributes &gt; 0; nCountAttributes--)
     {
      char* pszAttribName = 0;
      char* pszAttribVal = 0;
      char* pszPrefix = 0;
      int nErrCode = 0;
      
      pszPrefix = guththila_get_attribute_prefix_by_number(parser, nCountAttributes, env);
      if(pszPrefix)
      {
       AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "Prefix: \"%s\"", pszPrefix);
       AXIS2_FREE(env-&gt;allocator, pszPrefix);
       pszPrefix = 0;
      }

      pszAttribName = guththila_get_attribute_name_by_number(parser, nCountAttributes, env);

      if(!pszAttribName)
       break;
      
      AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "AttribName: \"%s\"", pszAttribName);      
      printf(" %s=", pszAttribName);
      
      pszAttribVal = guththila_get_attribute_value_by_number(parser, nCountAttributes, env);

      if(!pszAttribVal)
      {
       AXIS2_FREE(env-&gt;allocator, pszAttribName);
       pszAttribName = 0;
       break;
      }
      
      AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "AttribVal: \"%s\"", pszAttribVal);      
      printf("\"%s\"", pszAttribVal);

      AXIS2_FREE(env-&gt;allocator, pszAttribName);
      pszAttribName = 0;

      AXIS2_FREE(env-&gt;allocator, pszAttribVal);
      pszAttribVal = 0;
     }
     
     if(evt == GUTHTHILA_START_ELEMENT)
     {
      printf("&gt;\n");     
     }
     else
     {
      printf("/&gt;\n");
     }          
    }    
    break;
   case GUTHTHILA_END_ELEMENT:
    {
     char* pszName = 0;
     AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "GUTHTHILA_END_ELEMENT");     
     pszName = guththila_get_name(parser, env);
     
     if(pszName)
     {
      AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "Name: \"%s\"", pszName);

      PrintSpaces(parser-&gt;elem.top + 1);
      printf("&lt;/%s&gt;\n", pszName);

      AXIS2_FREE(env-&gt;allocator, pszName);
      pszName = 0;
     }
    }
    break;
   case GUTHTHILA_CHARACTER:
    { 
     AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "GUTHTHILA_CHARACTER");
    }
    break;
   case GUTHTHILA_COMMENT:
    {
     AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "GUTHTHILA_COMMENT");
    }
    break;
   case GUTHTHILA_SPACE:
    {
     AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "GUTHTHILA_SPACE");
    }   
    break;
   case GUTHTHILA_ENTITY_REFERANCE:
    {
     AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "GUTHTHILA_ENTITY_REFERANCE");
    }
    break;
  };  
 }
}

int GetBookInfo(guththila_t* parser, axutil_env_t* env, book_info* pBookInfo)
{
 int evt = 0;
 bool bTargetGenreNodeFound = false;
 bool bTargetAuthorNodeFound = false;
 bool bTargetBookNodeFound = false;

 AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "GetBookInfo()");
 AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "Number of elements in guththila stack: %d", parser-&gt;elem.top);

 while((evt = guththila_next(parser, env)) != -1)
 {
  AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "Number of elements in guththila stack: %d", parser-&gt;elem.top);

  switch(evt)
  {
   case GUTHTHILA_START_DOCUMENT:
    { 
     AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "GUTHTHILA_START_DOCUMENT");
    }
    break;
   case GUTHTHILA_START_ELEMENT:
   case GUTHTHILA_EMPTY_ELEMENT:
    {
     char* pszElemName = 0;
     char* pszPrefix = 0;
     int nCountAttributes = 0;

     if(evt == GUTHTHILA_START_ELEMENT)
     {
      AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "GUTHTHILA_START_ELEMENT");
     }
     else
     {
      // empty element is one that does not have child elements; it can have attributes though
      AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "GUTHTHILA_EMPTY_ELEMENT");
     }

     pszPrefix = guththila_get_prefix(parser, env);

     if(pszPrefix)
     {
      AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "Prefix: \"%s\"", pszPrefix);
      AXIS2_FREE(env-&gt;allocator, pszPrefix);
      pszPrefix = 0;
     }
     
     // guththila_get_name returns 0 if current node (token) does not have name     
     pszElemName = guththila_get_name(parser, env);

     if(!pszElemName)
      break;
     
     AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "Name: \"%s\"", pszElemName);
     
     
     if(!bTargetGenreNodeFound)
     {
      AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "Is current node Genre node?");
      if(strcmp((const char*)pszElemName, (const char*)"Genre") != 0)
       break;

      AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "Current node is Genre node");
     }
     else
     {     
      if(!bTargetAuthorNodeFound)
      {
       AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "Is current node Author node?");
       if(strcmp((const char*)pszElemName, (const char*)"Author") != 0)
        break; 

       AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "Current node is Author node");
      }
      else
      {
       if(!bTargetBookNodeFound)
       {
        AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "Is current node Book node?");

        if(strcmp((const char*)pszElemName, (const char*)"Book") != 0)
         break;  

        AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "Current node is Book node");        
       }
       else
       {
        break;
       }
      }
     }    

     nCountAttributes = guththila_get_attribute_count(parser, env);
     AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "Number of attributes: %d", nCountAttributes);

     for(; nCountAttributes &gt; 0; nCountAttributes--)
     {
      char* pszAttribName = 0;
      char* pszAttribVal = 0;      
      int nErrCode = 0;
      
      //
      // Get attribute name
      //

      pszAttribName = guththila_get_attribute_name_by_number(parser, nCountAttributes, env);

      if(!pszAttribName)
       break;
      
      AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "AttribName: \"%s\"", pszAttribName);      

      //
      // Get attribute value
      //

      pszAttribVal = guththila_get_attribute_value_by_number(parser, nCountAttributes, env);

      if(!pszAttribVal)
      {
       AXIS2_FREE(env-&gt;allocator, pszAttribName);
       pszAttribName = 0;
       break;
      }
      
      AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "AttribVal: \"%s\"", pszAttribVal);
        
      //
      // Compare attribute 
      //

      if(strcmp(pszAttribName, "Name") == 0)
      {
       AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "Name=\"%s\"", (const char*)pszAttribVal);

       if((!bTargetGenreNodeFound) &amp;&amp; (strcmp(pszElemName, "Genre")== 0))
       {
        if((strcmp(pszAttribVal, pBookInfo-&gt;pszGenre) != 0))
         break;

        AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "Found Genre node with Name \"%s\"", pszAttribVal);

        bTargetGenreNodeFound = true;
        break;
       }

       if((!bTargetAuthorNodeFound) &amp;&amp; (strcmp(pszElemName, "Author")== 0))
       {        
        if(strcmp(pszAttribVal, pBookInfo-&gt;pszAuthor) != 0)
         break;

        AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "Found Author node with Name \"%s\"", pszAttribVal);
        bTargetAuthorNodeFound = true;
        break;
       }

       if((!bTargetBookNodeFound) &amp;&amp; (strcmp(pszElemName, "Book")== 0))
       {        
        if(strcmp(pszAttribVal, pBookInfo-&gt;pszName) != 0)
         break;

        AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "Found Book node with Name \"%s\"", pszAttribVal);
        bTargetBookNodeFound = true;        
       }
      }
      else if(strcmp(pszAttribName, "ISBN") == 0)
      {
       AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "ISBN: \"%s\"", (const char*)pszAttribVal);    
    
       nErrCode = CopyStrRealloc(&amp;(pBookInfo-&gt;pszISBN), (const char*)pszAttribVal);

       if(nErrCode)
       {
        AXIS2_LOG_ERROR(env-&gt;log, AXIS2_LOG_SI, "ERROR: CopyStrRealloc() returned %d", nErrCode);
        return nErrCode;
       }
           
       AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "pBookInfo-&gt;pszISBN = \"%s\"", (const char*)pBookInfo-&gt;pszISBN);
      }
      else if(strcmp(pszAttribName, "PublishingDate") == 0)
      {
       AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "PublishingDate: \"%s\"", (const char*)pszAttribVal);    
    
       nErrCode = CopyStrRealloc(&amp;(pBookInfo-&gt;pszPublishingDate), (const char*)pszAttribVal);

       if(nErrCode)
       {
        AXIS2_LOG_ERROR(env-&gt;log, AXIS2_LOG_SI, "ERROR: CopyStrRealloc() returned %d", nErrCode);
        return nErrCode;
       }
           
       AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "pBookInfo-&gt;pszPublishingDate = \"%s\"", (const char*)pBookInfo-&gt;pszPublishingDate);
      }      

      AXIS2_FREE(env-&gt;allocator, pszAttribName);
      pszAttribName = 0;

      AXIS2_FREE(env-&gt;allocator, pszAttribVal);
      pszAttribVal = 0;
     }

     AXIS2_FREE(env-&gt;allocator, pszElemName);
     pszElemName = 0;
    }    
    break;
   case GUTHTHILA_END_ELEMENT:
    {
     char* pszName = 0;
     AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "GUTHTHILA_END_ELEMENT");
     pszName = guththila_get_name(parser, env);

     if(pszName)
     {
      AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "Name: \"%s\"", pszName);
      AXIS2_FREE(env-&gt;allocator, pszName);
      pszName = 0;
     }
    }
    break;
   case GUTHTHILA_CHARACTER:
    { 
     AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "GUTHTHILA_CHARACTER");
    }
    break;
   case GUTHTHILA_COMMENT:
    {
     AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "GUTHTHILA_COMMENT");
    }
    break;
  };

  if(bTargetGenreNodeFound &amp;&amp; bTargetAuthorNodeFound &amp;&amp; bTargetBookNodeFound)
   break;
 }

 AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "~GetBookInfo()");

 return 0;
}

int main()
{
 axutil_env_t* env = 0;
 const char* pszLogFilePath = "GuththilaTest.log";
 const char* pszXMLFilePath = "books.xml";
 guththila_t* parser = 0;
 guththila_reader_t* reader = 0;
 book_info bookInfo;
  
 env = axutil_env_create_all(pszLogFilePath, AXIS2_LOG_LEVEL_TRACE);

 if(!env)
 {     
  printf("Failed to create an environment\n");
  return 1;
 } 

 AXIS2_LOG_USER(env-&gt;log, AXIS2_LOG_SI, "\n\n\n");

 if(guth_init(&amp;reader, &amp;parser, env, pszXMLFilePath) != 0)
  goto cleanup_out; 

 ReadXML(parser, env); 

 guth_clean(&amp;reader, &amp;parser, env);

 if(guth_init(&amp;reader, &amp;parser, env, pszXMLFilePath) != 0)
  goto cleanup_out; 
 
 bookInfo.pszGenre = "Fiction";
 bookInfo.pszAuthor = "Fyodor Dostoyevsky";
 bookInfo.pszName = "Brothers Karamazov";
 bookInfo.pszISBN = 0;
 bookInfo.pszPublishingDate = 0; 
 
 if(GetBookInfo(parser, env, &amp;bookInfo) == 0)
 {
  printf("\nDetails for book \"%s\" found: ISBN=\"%s\", PublishingDate=\"%s\"", bookInfo.pszName, bookInfo.pszISBN, bookInfo.pszPublishingDate);
 }
 else
 {
  AXIS2_LOG_ERROR(env-&gt;log, AXIS2_LOG_SI, "GetBookInfo() failed");
 }

cleanup_out:

 guth_clean(&amp;reader, &amp;parser, env);
 
 if(env)
 {  
        axutil_env_free(env);  
        env = 0;
 }
 
 return 0;
}
]]&gt;
&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
This is the output:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="cmd_line"&gt;
&lt;br /&gt;
..\GuththilaTest\Debug&amp;gt;GuththilaTest.exe&lt;br /&gt;
AXIS2C_HOME is not set - log is written to . dir&lt;br /&gt;
&amp;nbsp;&amp;lt;books&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;Genre Name="Biography"&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&amp;lt;Author Name="Michael Moore"&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;lt;Book PublishingDate="13-Sep-2011" ISBN="9780713997019" Name="Here Comes Tro&lt;br /&gt;
uble"/&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&amp;lt;/Author&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&amp;lt;Author Name="Alan Sugar"&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;lt;Book PublishingDate="29-Sep-2011" ISBN="9780230760899" Name="Way I See it"/&lt;br /&gt;
&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&amp;lt;/Author&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;/Genre&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;Genre Name="Fiction"&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&amp;lt;Author Name="Ivo Andric"&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;lt;Book PublishingDate="05-Apr-1994" ISBN="9781860460586" Name="Bridge Over th&lt;br /&gt;
e Drina"/&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&amp;lt;/Author&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&amp;lt;Author Name="Fyodor Dostoyevsky"&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;lt;Book PublishingDate="30-Oct-2008" ISBN="9780955816949" Name="Crime and Puni&lt;br /&gt;
shment"/&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;lt;Book PublishingDate="27-Feb-2003" ISBN="9780140449242" Name="Brothers Karam&lt;br /&gt;
azov"/&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&amp;lt;/Author&amp;gt;&lt;br /&gt;
&amp;nbsp; &amp;lt;/Genre&amp;gt;&lt;br /&gt;
&amp;nbsp;&amp;lt;/books&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Details for book "Brothers Karamazov" found: ISBN="9780140449242", PublishingDat&lt;br /&gt;
e="27-Feb-2003"&lt;br /&gt;
..\GuththilaTest\Debug&amp;gt;&lt;/div&gt;
&lt;br /&gt;
And this is the content of the log file:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="black_border"&gt;
[Fri Oct 14 19:49:18 2011] [debug] c:\development\research\c\guththilatest\guththilatest\main.c(595)&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(534) reader created&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(517) DebugReader()&lt;br /&gt;
buff_size=-1163005939&lt;br /&gt;
type=1&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(553) parser created&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(502) DebugParser()&lt;br /&gt;
guththila_event=-1&lt;br /&gt;
last_start=-1&lt;br /&gt;
name=0&lt;br /&gt;
next=0&lt;br /&gt;
status=1&lt;br /&gt;
&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(517) DebugReader()&lt;br /&gt;
buff_size=-1163005939&lt;br /&gt;
type=1&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 0&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(103) GUTHTHILA_START_DOCUMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 0&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(239) GUTHTHILA_SPACE&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 1&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(115) GUTHTHILA_START_ELEMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(142) Name: "books"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(149) Number of attributes: 0&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 1&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(239) GUTHTHILA_SPACE&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 2&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(115) GUTHTHILA_START_ELEMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(142) Name: "Genre"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(149) Number of attributes: 1&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(177) AttribName: "Name"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(189) AttribVal: "Biography"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 2&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(239) GUTHTHILA_SPACE&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 3&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(115) GUTHTHILA_START_ELEMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(142) Name: "Author"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(149) Number of attributes: 1&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(177) AttribName: "Name"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(189) AttribVal: "Michael Moore"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 3&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(239) GUTHTHILA_SPACE&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 4&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(120) GUTHTHILA_EMPTY_ELEMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(142) Name: "Book"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(149) Number of attributes: 3&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(177) AttribName: "PublishingDate"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(189) AttribVal: "13-Sep-2011"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(177) AttribName: "ISBN"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(189) AttribVal: "9780713997019"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(177) AttribName: "Name"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(189) AttribVal: "Here Comes Trouble"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 3&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(239) GUTHTHILA_SPACE&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 2&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(212) GUTHTHILA_END_ELEMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(217) Name: "Author"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 2&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(239) GUTHTHILA_SPACE&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 3&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(115) GUTHTHILA_START_ELEMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(142) Name: "Author"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(149) Number of attributes: 1&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(177) AttribName: "Name"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(189) AttribVal: "Alan Sugar"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 3&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(239) GUTHTHILA_SPACE&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 4&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(120) GUTHTHILA_EMPTY_ELEMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(142) Name: "Book"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(149) Number of attributes: 3&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(177) AttribName: "PublishingDate"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(189) AttribVal: "29-Sep-2011"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(177) AttribName: "ISBN"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(189) AttribVal: "9780230760899"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(177) AttribName: "Name"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(189) AttribVal: "Way I See it"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 3&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(239) GUTHTHILA_SPACE&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 2&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(212) GUTHTHILA_END_ELEMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(217) Name: "Author"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 2&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(239) GUTHTHILA_SPACE&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 1&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(212) GUTHTHILA_END_ELEMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(217) Name: "Genre"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 1&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(239) GUTHTHILA_SPACE&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 2&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(115) GUTHTHILA_START_ELEMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(142) Name: "Genre"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(149) Number of attributes: 1&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(177) AttribName: "Name"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(189) AttribVal: "Fiction"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 2&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(239) GUTHTHILA_SPACE&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 3&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(115) GUTHTHILA_START_ELEMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(142) Name: "Author"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(149) Number of attributes: 1&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(177) AttribName: "Name"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(189) AttribVal: "Ivo Andric"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 3&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(239) GUTHTHILA_SPACE&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 4&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(120) GUTHTHILA_EMPTY_ELEMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(142) Name: "Book"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(149) Number of attributes: 3&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(177) AttribName: "PublishingDate"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(189) AttribVal: "05-Apr-1994"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(177) AttribName: "ISBN"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(189) AttribVal: "9781860460586"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(177) AttribName: "Name"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(189) AttribVal: "Bridge Over the Drina"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 3&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(239) GUTHTHILA_SPACE&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 2&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(212) GUTHTHILA_END_ELEMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(217) Name: "Author"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 2&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(239) GUTHTHILA_SPACE&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 3&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(115) GUTHTHILA_START_ELEMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(142) Name: "Author"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(149) Number of attributes: 1&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(177) AttribName: "Name"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(189) AttribVal: "Fyodor Dostoyevsky"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 3&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(239) GUTHTHILA_SPACE&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 4&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(120) GUTHTHILA_EMPTY_ELEMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(142) Name: "Book"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(149) Number of attributes: 3&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(177) AttribName: "PublishingDate"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(189) AttribVal: "30-Oct-2008"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(177) AttribName: "ISBN"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(189) AttribVal: "9780955816949"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(177) AttribName: "Name"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(189) AttribVal: "Crime and Punishment"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 3&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(239) GUTHTHILA_SPACE&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 4&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(120) GUTHTHILA_EMPTY_ELEMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(142) Name: "Book"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(149) Number of attributes: 3&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(177) AttribName: "PublishingDate"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(189) AttribVal: "27-Feb-2003"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(177) AttribName: "ISBN"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(189) AttribVal: "9780140449242"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(177) AttribName: "Name"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(189) AttribVal: "Brothers Karamazov"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 3&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(239) GUTHTHILA_SPACE&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 2&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(212) GUTHTHILA_END_ELEMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(217) Name: "Author"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 2&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(239) GUTHTHILA_SPACE&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 1&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(212) GUTHTHILA_END_ELEMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(217) Name: "Genre"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 1&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(239) GUTHTHILA_SPACE&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(97) Number of elements in guththila stack: 0&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(212) GUTHTHILA_END_ELEMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(217) Name: "books"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(566) guththila_reader_free() ok&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(573) guththila_un_init() ok&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(534) reader created&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(517) DebugReader()&lt;br /&gt;
buff_size=-1163005939&lt;br /&gt;
type=1&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(553) parser created&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(502) DebugParser()&lt;br /&gt;
guththila_event=-1&lt;br /&gt;
last_start=-1&lt;br /&gt;
name=0&lt;br /&gt;
next=0&lt;br /&gt;
status=1&lt;br /&gt;
&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(517) DebugReader()&lt;br /&gt;
buff_size=-1163005939&lt;br /&gt;
type=1&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(267) GetBookInfo()&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(268) Number of elements in guththila stack: 0&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(272) Number of elements in guththila stack: 0&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(278) GUTHTHILA_START_DOCUMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(272) Number of elements in guththila stack: 0&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(272) Number of elements in guththila stack: 1&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(290) GUTHTHILA_START_ELEMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(313) Name: "books"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(318) Is current node Genre node?&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(272) Number of elements in guththila stack: 1&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(272) Number of elements in guththila stack: 2&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(290) GUTHTHILA_START_ELEMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(313) Name: "Genre"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(318) Is current node Genre node?&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(322) Current node is Genre node&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(353) Number of attributes: 1&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(370) AttribName: "Name"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(385) AttribVal: "Biography"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(393) Name="Biography"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(272) Number of elements in guththila stack: 2&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(272) Number of elements in guththila stack: 3&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(290) GUTHTHILA_START_ELEMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(313) Name: "Author"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(318) Is current node Genre node?&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(272) Number of elements in guththila stack: 3&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(272) Number of elements in guththila stack: 4&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(295) GUTHTHILA_EMPTY_ELEMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(313) Name: "Book"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(318) Is current node Genre node?&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(272) Number of elements in guththila stack: 3&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(272) Number of elements in guththila stack: 2&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(468) GUTHTHILA_END_ELEMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(473) Name: "Author"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(272) Number of elements in guththila stack: 2&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(272) Number of elements in guththila stack: 3&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(290) GUTHTHILA_START_ELEMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(313) Name: "Author"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(318) Is current node Genre node?&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(272) Number of elements in guththila stack: 3&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(272) Number of elements in guththila stack: 4&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(295) GUTHTHILA_EMPTY_ELEMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(313) Name: "Book"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(318) Is current node Genre node?&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(272) Number of elements in guththila stack: 3&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(272) Number of elements in guththila stack: 2&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(468) GUTHTHILA_END_ELEMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(473) Name: "Author"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(272) Number of elements in guththila stack: 2&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(272) Number of elements in guththila stack: 1&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(468) GUTHTHILA_END_ELEMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(473) Name: "Genre"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(272) Number of elements in guththila stack: 1&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(272) Number of elements in guththila stack: 2&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(290) GUTHTHILA_START_ELEMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(313) Name: "Genre"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(318) Is current node Genre node?&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(322) Current node is Genre node&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(353) Number of attributes: 1&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(370) AttribName: "Name"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(385) AttribVal: "Fiction"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(393) Name="Fiction"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(400) Found Genre node with Name "Fiction"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(272) Number of elements in guththila stack: 2&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(272) Number of elements in guththila stack: 3&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(290) GUTHTHILA_START_ELEMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(313) Name: "Author"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(328) Is current node Author node?&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(332) Current node is Author node&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(353) Number of attributes: 1&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(370) AttribName: "Name"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(385) AttribVal: "Ivo Andric"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(393) Name="Ivo Andric"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(272) Number of elements in guththila stack: 3&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(272) Number of elements in guththila stack: 4&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(295) GUTHTHILA_EMPTY_ELEMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(313) Name: "Book"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(328) Is current node Author node?&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(272) Number of elements in guththila stack: 3&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(272) Number of elements in guththila stack: 2&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(468) GUTHTHILA_END_ELEMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(473) Name: "Author"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(272) Number of elements in guththila stack: 2&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(272) Number of elements in guththila stack: 3&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(290) GUTHTHILA_START_ELEMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(313) Name: "Author"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(328) Is current node Author node?&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(332) Current node is Author node&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(353) Number of attributes: 1&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(370) AttribName: "Name"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(385) AttribVal: "Fyodor Dostoyevsky"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(393) Name="Fyodor Dostoyevsky"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(411) Found Author node with Name "Fyodor Dostoyevsky"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(272) Number of elements in guththila stack: 3&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(272) Number of elements in guththila stack: 4&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(295) GUTHTHILA_EMPTY_ELEMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(313) Name: "Book"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(338) Is current node Book node?&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(343) Current node is Book node&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(353) Number of attributes: 3&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(370) AttribName: "PublishingDate"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(385) AttribVal: "30-Oct-2008"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(441) PublishingDate: "30-Oct-2008"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(451) pBookInfo-&amp;gt;pszPublishingDate = "30-Oct-2008"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(370) AttribName: "ISBN"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(385) AttribVal: "9780955816949"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(427) ISBN: "9780955816949"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(437) pBookInfo-&amp;gt;pszISBN = "9780955816949"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(370) AttribName: "Name"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(385) AttribVal: "Crime and Punishment"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(393) Name="Crime and Punishment"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(272) Number of elements in guththila stack: 3&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(272) Number of elements in guththila stack: 4&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(295) GUTHTHILA_EMPTY_ELEMENT&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(313) Name: "Book"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(338) Is current node Book node?&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(343) Current node is Book node&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(353) Number of attributes: 3&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(370) AttribName: "PublishingDate"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(385) AttribVal: "27-Feb-2003"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(441) PublishingDate: "27-Feb-2003"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(451) pBookInfo-&amp;gt;pszPublishingDate = "27-Feb-2003"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(370) AttribName: "ISBN"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(385) AttribVal: "9780140449242"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(427) ISBN: "9780140449242"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(437) pBookInfo-&amp;gt;pszISBN = "9780140449242"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(370) AttribName: "Name"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(385) AttribVal: "Brothers Karamazov"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(393) Name="Brothers Karamazov"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(421) Found Book node with Name "Brothers Karamazov"&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(495) ~GetBookInfo()&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(566) guththila_reader_free() ok&lt;br /&gt;
[Fri Oct 14 19:49:18 2011] [debug] \guththilatest\main.c(573) guththila_un_init() ok&lt;/div&gt;
&lt;br /&gt;
Please be aware that &lt;span class="Apple-style-span" style="color: red;"&gt;Guththila is not intended for direct use&lt;/span&gt; but through its wrapper, axis2_parser [&lt;a href="http://wsaxc.blogspot.com/2008/06/developers-quick-start-guide-for-axis2c.html"&gt;link&lt;/a&gt;]. That is probably the reason why there is no documentation about it available on the Internet.&lt;br /&gt;
&lt;br /&gt;
axis2_parser is XML parser abstraction layer which can be either guththila or libxml2 wrapper. In the first case (in Axis2/C binary package),&amp;nbsp;axis2_parser.dll depends on guththila.dll. In the second case (in custom Axis2/C builds),&amp;nbsp;axis2_parser.dll depends on libxm2.dll, zlib1.dll and iconv.dll.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4912226416400969049-1737247028752134456?l=bojan-komazec.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/8JFWR9H7P4TaLe1tS6pYBA9lCIw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8JFWR9H7P4TaLe1tS6pYBA9lCIw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/8JFWR9H7P4TaLe1tS6pYBA9lCIw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/8JFWR9H7P4TaLe1tS6pYBA9lCIw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/MyPublicNotepad/~4/odWca8tZ8aI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://bojan-komazec.blogspot.com/feeds/1737247028752134456/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4912226416400969049&amp;postID=1737247028752134456" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/1737247028752134456?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/1737247028752134456?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyPublicNotepad/~3/odWca8tZ8aI/reading-xml-with-guththila.html" title="Reading XML with Guththila" /><author><name>Bojan Komazec</name><uri>https://profiles.google.com/117174187628268281803</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://bojan-komazec.blogspot.com/2011/10/reading-xml-with-guththila.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkUFSXY5cCp7ImA9WhdbFU0.&quot;"><id>tag:blogger.com,1999:blog-4912226416400969049.post-2908942374932176914</id><published>2011-10-13T11:03:00.000+01:00</published><updated>2011-10-13T11:03:38.828+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-13T11:03:38.828+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Debugging" /><category scheme="http://www.blogger.com/atom/ns#" term="MFC" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><category scheme="http://www.blogger.com/atom/ns#" term="GUI" /><title>What to do when sending message to some window fails or crashes the application</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
You want to send a message from one window to another by calling &lt;b&gt;CWnd::SendMessage(...)&lt;/b&gt; or&amp;nbsp;&lt;b&gt;CWnd::PostMessage(...)&lt;/b&gt; and application crashes during these calls. How to find the cause of the crash?&lt;br /&gt;
&lt;br /&gt;
We first need to determine the nature of the crash. Open crash dump, read message in Windows Debugger Dialog Box, read log file&amp;nbsp;(if any). Functions above are called on the window through its pointer so check whether pointer is valid (not NULL - in which case you'll have access violation exception). Get window's handle and check whether it's valid (&lt;b&gt;IsWindow(...)&lt;/b&gt;). If message is supposed to be sent to window's parent/owner, make sure that sending and receiving window are of proper type and in desired relation (parent/child or owner/owned).&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="color: red;"&gt;It is very important to understand types of windows and relationships between them.&lt;/span&gt; They are all set at the time of window creation.&lt;br /&gt;
&lt;br /&gt;
When creating some window with &lt;b&gt;Create(...)&lt;/b&gt;/&lt;b&gt;CreateEx(...)&lt;/b&gt; we need to pass two important arguments to these functions:&lt;br /&gt;
1) window styles&lt;br /&gt;
2) parent/owner window&lt;br /&gt;
&lt;br /&gt;
Window styles define the nature (type) of the window and its appearance. There are three types of windows: &lt;b&gt;overlapped&lt;/b&gt;, &lt;b&gt;pop-up&lt;/b&gt; and &lt;b&gt;child&lt;/b&gt;. For example, main application window is an overlapped window, which has some embedded controls (e.g. buttons) and these controls are child windows. When we press some of those buttons, a dialog box can appear and dialog box is a pop-up window. Each of these three types has its own flag within Window styles and they are defined in &lt;b&gt;WinUser.h&lt;/b&gt;:&amp;nbsp;&lt;b&gt;WS_OVERLAPPED &lt;/b&gt;(0x00000000L),&amp;nbsp;&lt;b&gt;WS_POPUP &lt;/b&gt;(0x80000000L),&amp;nbsp;&lt;b&gt;WS_CHILD &lt;/b&gt;(0x40000000L). Window style can have only one of these flags set (e.g. window cannot be pop-up and child at the same time). If you omit setting style, your window will be overlapped by default and no matter the fact you passed the pointer/handler of some window as its e.g. parent, you might not get expected behaviour as this window will not actually be of a child type!&lt;br /&gt;
&lt;br /&gt;
When passing pointer or handler to parent/owner window, make sure that pointer is not NULL, and that handler is a valid handler of parent/owner at the time of the creation of child/owned window (use &lt;b&gt;IsWindow()&lt;/b&gt;).&lt;br /&gt;
&lt;br /&gt;
Do the same for window you're calling SendMessage/PostMessage on.&lt;br /&gt;
&lt;br /&gt;
You can use this helper function which analyses some arbitrary window:&lt;br /&gt;
&lt;br /&gt;
WndHelper.h:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="my_code"&gt;
#ifndef _WNDHELPER_H&lt;br /&gt;
#define _WNDHELPER_H&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;afxwin.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Usage:&lt;br /&gt;
// CWnd* pWnd = ...&lt;br /&gt;
// AnalyzeWnd(pWnd);&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;br /&gt;
void AnalyzeWnd(const CWnd* pWnd);&lt;br /&gt;
&lt;br /&gt;
#endif // _WNDHELPER_H&lt;/div&gt;
&lt;br /&gt;
WndHelper.cpp:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="my_code"&gt;
&lt;br /&gt;
#include "Include\WndHelper.h"&lt;br /&gt;
&lt;br /&gt;
void AnalyzeWnd(const CWnd* pWnd)&lt;br /&gt;
{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;TRACE(_T("AnalyzeWnd()"));&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;if(!pWnd)&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;TRACE(_T("pWnd is NULL!"));&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;return;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;//&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;// Get Desktop&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;//&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;CWnd* pWndDesktop = pWnd-&amp;gt;GetDesktopWindow();&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;if(pWndDesktop)&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;TRACE(_T("GetDesktopWindow() returned valid window pointer. pWndDesktop = %p"), pWndDesktop);&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;HWND hWndDesktop = pWndDesktop-&amp;gt;GetSafeHwnd();&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;TRACE(_T("hWndDesktop = %p"), hWndDesktop);&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;else&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;TRACE(_T("GetDesktopWindow() returned NULL!"));&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;//&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;// Analyze Window&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;//&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;TRACE(_T("pWnd = %p"), pWnd);&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;HWND hWnd = pWnd-&amp;gt;GetSafeHwnd();&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;if(::IsWindow(hWnd))&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;TRACE(_T("GetSafeHwnd() returned valid window handle. hWnd = %p"), hWnd);&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;else&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;TRACE(_T("GetSafeHwnd() returned INVALID window handle!"));&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;if(::IsWindow(pWnd-&amp;gt;m_hWnd))&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;TRACE(_T("m_hWnd is a valid window handle. pWnd-&amp;gt;m_hWnd = %p"), pWnd-&amp;gt;m_hWnd);&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;TRACE(_T("Window styles: "));&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;LONG lStyle = ::GetWindowLong(pWnd-&amp;gt;m_hWnd, GWL_STYLE);&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;if(lStyle == WS_OVERLAPPED) // 0&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;TRACE(_T("\t\tWS_OVERLAPPED (0)"));&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;}&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;else&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;{&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;if((lStyle &amp;amp; WS_POPUP) == WS_POPUP)&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;    &lt;/span&gt;TRACE(_T("\t\tWS_POPUP"));&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;if((lStyle &amp;amp; WS_CHILD) == WS_CHILD)&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;    &lt;/span&gt;TRACE(_T("\t\tWS_CHILD"));&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;if((lStyle &amp;amp; WS_VISIBLE) == WS_VISIBLE)&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;    &lt;/span&gt;TRACE(_T("\t\tWS_VISIBLE"));&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;if((lStyle &amp;amp; WS_DISABLED) == WS_DISABLED)&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;    &lt;/span&gt;TRACE(_T("\t\tWS_DISABLED"));&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;if((lStyle &amp;amp; WS_CAPTION) == WS_CAPTION)&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;    &lt;/span&gt;TRACE(_T("\t\tWS_CAPTION"));&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;if((lStyle &amp;amp; WS_BORDER) == WS_BORDER)&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;    &lt;/span&gt;TRACE(_T("\t\tWS_BORDER"));&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;if((lStyle &amp;amp; WS_DLGFRAME) == WS_DLGFRAME)&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;    &lt;/span&gt;LOGGER_PRINTF(Debug, _T("\t\tWS_DLGFRAME"));&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;if((lStyle &amp;amp; WS_SYSMENU) == WS_SYSMENU)&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;    &lt;/span&gt;TRACE(_T("\t\tWS_SYSMENU"));&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;// todo: add checks for other styles...&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;}&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;// todo: check extended styles&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;// LONG lStyleEx = GetWindowLong(GetSafeHwnd(), GWL_EXSTYLE);&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;else&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;TRACE(_T("pWnd-&amp;gt;m_hWnd is an INVALID window handle!"));&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;hWnd = pWnd-&amp;gt;m_hWndOwner;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;if(::IsWindow(hWnd))&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;TRACE(_T("m_hWndOwner is a valid window handle. m_hWndOwner = %p"), hWnd);&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;else&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;TRACE(_T("m_hWndOwner is an INVALID window handle!"));&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;//&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;// Analyze Parent&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;//&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;CWnd* pWndParent = pWnd-&amp;gt;GetParent();&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;if(pWndParent)&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;TRACE(_T("GetParent() returned valid pointer. pWndParent = %p"), pWndParent);&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;HWND hWnd = pWndParent-&amp;gt;GetSafeHwnd();&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;if(::IsWindow(hWnd))&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;TRACE(_T("GetSafeHwnd() returned valid window handle. hWnd = %p"), hWnd);&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;}&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;else&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;TRACE(_T("GetSafeHwnd() returned INVALID window handle!"));&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;}&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;else&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;TRACE(_T("GetParent() returned NULL!"));&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;CWnd* pWndParentOwner = pWnd-&amp;gt;GetParentOwner();&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;if(pWndParentOwner)&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;TRACE(_T("GetParentOwner() returned valid pointer. pWndParentOwner = %p"), pWndParentOwner);&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;HWND hWnd = pWndParentOwner-&amp;gt;GetSafeHwnd();&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;if(::IsWindow(hWnd))&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;TRACE(_T("GetSafeHwnd() returned valid window handle. hWnd = %p"), hWnd);&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;}&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;else&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;TRACE(_T("GetSafeHwnd() returned INVALID window handle!"));&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;}&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;else&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;TRACE(_T("GetParentOwner() returned NULL!"));&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;//&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;// Analyze Owner&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;//&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;     &lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;CWnd* pWndOwner = pWnd-&amp;gt;GetOwner();&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;if(pWndOwner)&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;TRACE(_T("GetOwner() returned valid pointer. pWndOwner = %p"), pWndOwner);&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;HWND hWnd = pWndOwner-&amp;gt;GetSafeHwnd();&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;if(::IsWindow(hWnd))&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;TRACE(_T("GetSafeHwnd() returned valid window handle. hWnd = %p"), hWnd);&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;}&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;else&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;TRACE(_T("GetSafeHwnd() returned INVALID window handle!"));&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;}&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;else&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;TRACE(_T("GetOwner() returned NULL!"));&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;CWnd* pWndSafeOwner = pWnd-&amp;gt;GetSafeOwner();&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;if(pWndSafeOwner)&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;TRACE(_T("GetSafeOwner() returned valid pointer. pWndSafeOwner = %p"), pWndSafeOwner);&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;HWND hWnd = pWndSafeOwner-&amp;gt;GetSafeHwnd();&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;if(::IsWindow(hWnd))&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;TRACE(_T("GetSafeHwnd() returned valid window handle. hWnd = %p"), hWnd);&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;}&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;else&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;TRACE(_T("GetSafeHwnd() returned INVALID window handle!"));&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;}&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;else&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;TRACE(_T("GetSafeOwner() returned NULL!"));&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;br /&gt;
}&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
Links and references:&lt;br /&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/t64sseb3.aspx"&gt;CWnd::SendMessage (MSDN)&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/9tdesxec.aspx"&gt;CWnd::PostMessage (MSDN)&lt;/a&gt;&lt;div&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/ms633528(VS.85).aspx"&gt;IsWindow (MSDN)&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/0yhc9kx4.aspx"&gt;CWnd::Create (MSDN)&lt;/a&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/atzdh4ys.aspx"&gt;CWnd::CreateEx (MSDN)&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4912226416400969049-2908942374932176914?l=bojan-komazec.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/eDag12-dl-dnZVKR6NyYogLN_Lc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/eDag12-dl-dnZVKR6NyYogLN_Lc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/eDag12-dl-dnZVKR6NyYogLN_Lc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/eDag12-dl-dnZVKR6NyYogLN_Lc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/MyPublicNotepad/~4/engYo80blpk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://bojan-komazec.blogspot.com/feeds/2908942374932176914/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4912226416400969049&amp;postID=2908942374932176914" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/2908942374932176914?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/2908942374932176914?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyPublicNotepad/~3/engYo80blpk/what-to-do-when-sending-message-to-some.html" title="What to do when sending message to some window fails or crashes the application" /><author><name>Bojan Komazec</name><uri>https://profiles.google.com/117174187628268281803</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://bojan-komazec.blogspot.com/2011/10/what-to-do-when-sending-message-to-some.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C08FQX0_fCp7ImA9WhdbEEw.&quot;"><id>tag:blogger.com,1999:blog-4912226416400969049.post-6027706187087047054</id><published>2011-10-07T19:23:00.001+01:00</published><updated>2011-10-07T19:23:30.344+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-07T19:23:30.344+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Axis2C" /><category scheme="http://www.blogger.com/atom/ns#" term="IIS" /><title>Minimal Axis2C Web Service package needed for deployment with IIS</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;If Axis2/C engine does not support OpenSSL and does not use libxml2 as XML parser, this is the minimal set of Axis2C files needed to be deployed on the machine with IIS in order to support hosting MyWebService Axis2/C Web Service:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="file_hierarchy"&gt;C:\axis2c\lib\axiom.dll&lt;br /&gt;
C:\axis2c\lib\axis2_engine.dll&lt;br /&gt;
C:\axis2c\lib\axis2_http_receiver.dll&lt;br /&gt;
C:\axis2c\lib\axis2_http_sender.dll&lt;br /&gt;
C:\axis2c\lib\axis2_parser.dll&lt;br /&gt;
C:\axis2c\lib\axis2_xpath.dll&lt;br /&gt;
C:\axis2c\lib\axutil.dll&lt;br /&gt;
C:\axis2c\lib\guththila.dll&lt;br /&gt;
C:\axis2c\lib\mod_axis2_IIS.dll&lt;br /&gt;
C:\axis2c\lib\neethi.dll&lt;br /&gt;
&lt;br /&gt;
C:\axis2c\modules\addressing&lt;br /&gt;
C:\axis2c\modules\addressing\axis2_mod_addr.dll&lt;br /&gt;
C:\axis2c\modules\addressing\module.xml&lt;br /&gt;
&lt;br /&gt;
C:\axis2c\services\MyWebService\MyWebService.dll&lt;br /&gt;
C:\axis2c\services\MyWebService\services.xml&lt;br /&gt;
&lt;br /&gt;
C:\axis2c\axis2.xml&lt;br /&gt;
C:\axis2c\LICENCE&lt;br /&gt;
C:\axis2c\NOTICE&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4912226416400969049-6027706187087047054?l=bojan-komazec.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/kZdD-22nLsCPTO0nU12QxZmDw00/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/kZdD-22nLsCPTO0nU12QxZmDw00/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/kZdD-22nLsCPTO0nU12QxZmDw00/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/kZdD-22nLsCPTO0nU12QxZmDw00/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/MyPublicNotepad/~4/b9Lnor0HlfE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://bojan-komazec.blogspot.com/feeds/6027706187087047054/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4912226416400969049&amp;postID=6027706187087047054" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/6027706187087047054?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/6027706187087047054?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyPublicNotepad/~3/b9Lnor0HlfE/minimal-axis2c-web-service-package.html" title="Minimal Axis2C Web Service package needed for deployment with IIS" /><author><name>Bojan Komazec</name><uri>https://profiles.google.com/117174187628268281803</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://bojan-komazec.blogspot.com/2011/10/minimal-axis2c-web-service-package.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkMERng9fyp7ImA9WhdbEE0.&quot;"><id>tag:blogger.com,1999:blog-4912226416400969049.post-6858489551507462850</id><published>2011-10-07T18:26:00.001+01:00</published><updated>2011-10-07T18:26:47.667+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-07T18:26:47.667+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Visual Studio" /><category scheme="http://www.blogger.com/atom/ns#" term="Resources" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><title>Conditional compilation of resource file in Visual Studio</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
&lt;span class="Apple-style-span" style="background-color: white; font-family: arial, helvetica, tahoma, sans-serif; font-size: 13px;"&gt;How to use different resources in different build configurations, having a single resource file in project?&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; font-family: arial, helvetica, tahoma, sans-serif; font-size: 13px;"&gt;Answer: define different&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="background-color: white; font-family: arial, helvetica, tahoma, sans-serif; font-size: 13px;"&gt;resource file&amp;nbsp;&lt;/span&gt;&lt;span class="Apple-style-span" style="background-color: white; font-family: arial, helvetica, tahoma, sans-serif; font-size: 13px;"&gt;preprocessor symbols for different configurations.&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; font-family: arial, helvetica, tahoma, sans-serif; font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; font-family: arial, helvetica, tahoma, sans-serif; font-size: 13px;"&gt;1. Open your project in Visual Studio 2008&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; font-family: arial, helvetica, tahoma, sans-serif; font-size: 13px;"&gt;&lt;br /&gt;2. Right click on resource script file (e.g. app.rc) and select "Properties"&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; font-family: arial, helvetica, tahoma, sans-serif; font-size: 13px;"&gt;&lt;br /&gt;3. At the top of the property page, select one platform like "Win32" or&amp;nbsp;"x64".&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; font-family: arial, helvetica, tahoma, sans-serif; font-size: 13px;"&gt;4. In the left menu bar, select [Configuration Properties] / [Resources] /&amp;nbsp;[General].&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; font-family: arial, helvetica, tahoma, sans-serif; font-size: 13px;"&gt;&lt;br /&gt;5. In the "Preprocessor Definitions" field, add "&lt;b&gt;WIN32&lt;/b&gt;" for "Win32"&amp;nbsp;platform and "&lt;b&gt;WIN64&lt;/b&gt;" for "x64" platform. The field value will become "WINXX;_UNICODE;UNICODE". (XX will be 32 or 64)&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; font-family: arial, helvetica, tahoma, sans-serif; font-size: 13px;"&gt;&lt;br /&gt;6. Click OK to close the window.&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; font-family: arial, helvetica, tahoma, sans-serif; font-size: 13px;"&gt;&lt;br /&gt;7. Right click on resource script file (e.g. app.rc) and select "View Code".&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; font-family: arial, helvetica, tahoma, sans-serif; font-size: 13px;"&gt;&lt;br /&gt;8. In the code editor, add #ifdef and #elif to conditionally include&amp;nbsp;resources when compiling. Use "&lt;b&gt;WIN32&lt;/b&gt;" and "&lt;b&gt;WIN64&lt;/b&gt;" preprocessor definitions&amp;nbsp;that we defined just now.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; font-family: arial, helvetica, tahoma, sans-serif; font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; font-family: arial, helvetica, tahoma, sans-serif; font-size: 13px;"&gt;Here is a sample code:&lt;br /&gt;--------------------------------&lt;br /&gt;#ifdef &lt;b&gt;WIN32&lt;/b&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;IDB_BITMAP1 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; BITMAP &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;"bitmap1.bmp"&lt;br /&gt;&amp;nbsp; &amp;nbsp;IDB_BITMAP2 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; BITMAP &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;"bitmap2.bmp"&lt;br /&gt;#elif &lt;b&gt;WIN64&lt;/b&gt;&lt;br /&gt;&amp;nbsp; &amp;nbsp;IDR_TOOLBAR1 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; BITMAP &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "toolbar1.bmp"&lt;br /&gt;&amp;nbsp; &amp;nbsp;IDI_ICON1 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ICON &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; "icon1.ico"&lt;br /&gt;#endif&lt;br /&gt;--------------------------------&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; font-family: arial, helvetica, tahoma, sans-serif; font-size: 13px;"&gt;9. Save the resource script file and compile the project in different&amp;nbsp;platforms.&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; font-family: arial, helvetica, tahoma, sans-serif; font-size: 13px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="background-color: white; font-family: arial, helvetica, tahoma, sans-serif; font-size: 13px;"&gt;[&lt;a href="http://www.dotnetmonster.com/Uwe/Forum.aspx/vs-net-general/12537/Resource-Compiler-distinction-x64-or-x86"&gt;source&lt;/a&gt;]&lt;/span&gt;&lt;/div&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4912226416400969049-6858489551507462850?l=bojan-komazec.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/S1H7f0DEZPNaQtNAUILUBvbaMF8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/S1H7f0DEZPNaQtNAUILUBvbaMF8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/S1H7f0DEZPNaQtNAUILUBvbaMF8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/S1H7f0DEZPNaQtNAUILUBvbaMF8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/MyPublicNotepad/~4/qckcTwgwI84" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://bojan-komazec.blogspot.com/feeds/6858489551507462850/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4912226416400969049&amp;postID=6858489551507462850" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/6858489551507462850?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/6858489551507462850?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyPublicNotepad/~3/qckcTwgwI84/conditional-compilation-of-resource.html" title="Conditional compilation of resource file in Visual Studio" /><author><name>Bojan Komazec</name><uri>https://profiles.google.com/117174187628268281803</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://bojan-komazec.blogspot.com/2011/10/conditional-compilation-of-resource.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEUCRnc7eyp7ImA9WhdbEUs.&quot;"><id>tag:blogger.com,1999:blog-4912226416400969049.post-3413160014386880751</id><published>2011-10-07T16:31:00.000+01:00</published><updated>2011-10-09T13:11:07.903+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-09T13:11:07.903+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Windows" /><category scheme="http://www.blogger.com/atom/ns#" term="Computer architecture" /><category scheme="http://www.blogger.com/atom/ns#" term="NSIS" /><title>NSIS installer for 64-bit Windows</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;Here are some tips for creating (32-bit) NSIS installer which installs 64-bit application on 64-bit Windows. &lt;br /&gt;
&lt;br /&gt;
There is no 64-bit NSIS Installer (yet) so only 32-bit version will be running on 64-bit host which means that 32-bit &lt;b&gt;redirection &lt;/b&gt;will take place: by default its Installation Directory is "C:\Program Files (x86)" and it reads/writes only from HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node portion of the registry. This is not what we want so we need to enable access to native Win64 directories/registry for our Installer.&lt;br /&gt;
&lt;br /&gt;
Our installer, as 32-bit application, will probably be used both for 32-bit and 64-bit installations. It therefore needs to be able to determine architecture of the CPU it runs on. &lt;b&gt;&lt;a href="http://nsis.sourceforge.net/Include/x64.nsh"&gt;x64&lt;/a&gt; &lt;/b&gt;plug-in offers macro &lt;b&gt;RunningX64 &lt;/b&gt;which returns true if installer is running on 64-bit Windows (under WoW64 emulation):&lt;br /&gt;
&lt;br /&gt;
setup.nsi:&lt;br /&gt;
&lt;div class="my_code"&gt;!include &lt;span class="Apple-style-span" style="color: red;"&gt;x64.nsh&lt;/span&gt;&lt;br /&gt;
...&lt;br /&gt;
${If} ${&lt;span class="Apple-style-span" style="color: red;"&gt;RunningX64&lt;/span&gt;} &lt;br /&gt;
&amp;nbsp; &amp;nbsp;DetailPrint "Installer running on 64-bit host"&lt;br /&gt;
${EndIf}&lt;/div&gt;&lt;br /&gt;
Once we've detected 64-bit host, we need to: &lt;br /&gt;
&lt;ul style="text-align: left;"&gt;&lt;li&gt;set "C:\Program Files" as Installation Directory - use &lt;b&gt;$PROGRAMFILES64&lt;/b&gt; instead of $PROGRAMFILES&lt;/li&gt;
&lt;li&gt;enable access to 64-bit registry - use &lt;b&gt;SetRegView &lt;/b&gt;NSIS command&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
setup.nsi:&lt;br /&gt;
&lt;div class="my_code"&gt;!include x64.nsh&lt;br /&gt;
&lt;br /&gt;
;set initial value for $INSTDIR&lt;br /&gt;
InstallDir "$PROGRAMFILES\${MY_COMPANY}\${MY_APP}"&lt;br /&gt;
...&lt;br /&gt;
${If} ${RunningX64} &lt;br /&gt;
&amp;nbsp; &amp;nbsp;DetailPrint "Installer running on 64-bit host"&lt;br /&gt;
&amp;nbsp; &amp;nbsp;; disable registry redirection (enable access to 64-bit portion of registry)&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&lt;span class="Apple-style-span" style="color: red;"&gt;SetRegView 64&lt;/span&gt;&lt;br /&gt;
&amp;nbsp; &amp;nbsp;; change install dir &lt;br /&gt;
&amp;nbsp; &amp;nbsp;StrCpy $INSTDIR "&lt;span class="Apple-style-span" style="color: red;"&gt;$PROGRAMFILES64&lt;/span&gt;\${BRAND_DIR}\${APOLLO_UPDATE_SERVER_DIR}"&lt;br /&gt;
${EndIf}&lt;/div&gt;&lt;br /&gt;
If installer needs to detect whether some 64-bit process is running, use &lt;a href="http://nsis.sourceforge.net/FindProcDLL_plug-in"&gt;&lt;b&gt;FindProcDLL &lt;/b&gt;plug-in&lt;/a&gt; (there are couple of versions available but I found only this one -&amp;nbsp;&lt;a href="http://forums.winamp.com/attachment.php?attachmentid=48888&amp;amp;d=1307099823"&gt;FindProcDLL_mod_by_hnedka.7z&lt;/a&gt;&amp;nbsp;-&amp;nbsp;working for me; please have a look at &lt;a href="http://forums.winamp.com/showthread.php?t=322583"&gt;this forum thread&lt;/a&gt;). Download this archived file, unpack it and copy FindProcDLL.dll to your ..\NSIS\Plugins directory.&lt;br /&gt;
&lt;br /&gt;
setup.nsi:&lt;br /&gt;
&lt;div class="my_code"&gt;${If} ${RunningX64}&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&lt;span class="Apple-style-span" style="color: red;"&gt;FindProcDLL::FindProc&lt;/span&gt; "Some64BitProcess.exe"&lt;br /&gt;
&amp;nbsp; &amp;nbsp;${If} $R0 == 1&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; DetailPrint "FindProcDLL::FindProc() returned 1 (process is running)"&lt;br /&gt;
&amp;nbsp; &amp;nbsp;${ElseIf} $R0 == 0&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; DetailPrint "FindProcDLL::FindProc() returned 0 (process is nor running)"&lt;br /&gt;
&amp;nbsp; &amp;nbsp;${Else}&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; DetailPrint "FindProcDLL::FindProc() returned unexpected value"                               &lt;br /&gt;
&amp;nbsp; &amp;nbsp;${Endif}                                                  &lt;br /&gt;
${Else} &lt;br /&gt;
...&lt;/div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4912226416400969049-3413160014386880751?l=bojan-komazec.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Rfy9FSu_W0_EAA_we2ELzgtFL6M/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Rfy9FSu_W0_EAA_we2ELzgtFL6M/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Rfy9FSu_W0_EAA_we2ELzgtFL6M/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Rfy9FSu_W0_EAA_we2ELzgtFL6M/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/MyPublicNotepad/~4/IKAfwIQeTxY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://bojan-komazec.blogspot.com/feeds/3413160014386880751/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4912226416400969049&amp;postID=3413160014386880751" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/3413160014386880751?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/3413160014386880751?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyPublicNotepad/~3/IKAfwIQeTxY/nsis-installer-for-64-bit-windows.html" title="NSIS installer for 64-bit Windows" /><author><name>Bojan Komazec</name><uri>https://profiles.google.com/117174187628268281803</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://bojan-komazec.blogspot.com/2011/10/nsis-installer-for-64-bit-windows.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE4CQno7eSp7ImA9WhdbEE0.&quot;"><id>tag:blogger.com,1999:blog-4912226416400969049.post-4407765391420011873</id><published>2011-10-07T15:12:00.000+01:00</published><updated>2011-10-07T16:56:03.401+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-07T16:56:03.401+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Axis2C" /><category scheme="http://www.blogger.com/atom/ns#" term="makefile" /><category scheme="http://www.blogger.com/atom/ns#" term="IIS" /><category scheme="http://www.blogger.com/atom/ns#" term="Windows" /><category scheme="http://www.blogger.com/atom/ns#" term="Computer architecture" /><category scheme="http://www.blogger.com/atom/ns#" term="NMAKE" /><title>How to build Axis2C for 64-bit Windows</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
This article shows how to build Axis2/C package for 64-bit Windows (AMD64 processor architecture) from command line, by using NMAKE that comes with Visual Studio 2010. Building this package for 32-bit Windows is described &lt;a href="http://axis.apache.org/axis2/c/core/docs/installationguide.html#2_3"&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Step 1:&lt;/span&gt;&lt;/b&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;Download source distribution for Windows from &lt;a href="http://axis.apache.org/axis2/c/core/download.cgi" target="_blank"&gt;Apache Axis2/C Releases page&lt;/a&gt;.  It comes as axis2c-src-1.6.0.zip file. Unzip it to some folder, e.g. "..\axis2c-src-1.6.0"&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Step 2:&lt;/span&gt;&lt;/b&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;Set NMAKE environment&lt;br /&gt;
&lt;b&gt;..\axis2c-src-1.6.0\build\win32\makefile&lt;/b&gt; is Microsoft's NMAKE makefile and &lt;b&gt;..\axis2c-src-1.6.0\build\win32\configure.in&lt;/b&gt; is its configuration file. As I explained in the article &lt;a href="http://bojan-komazec.blogspot.com/2011/10/nmake-and-its-environment.html" target="_blank"&gt;"NMAKE and its environment"&lt;/a&gt;, in order to compile code targeting 64-bit OS on 32-bit host NMAKE needs to use cross-compiler and linker, it needs to be able to access headers for 64-bit code, and 64-bit libraries. To achieve this we need to set environment variables in the current command prompt session which can be done in couple of ways:&lt;br /&gt;
&lt;ul style="text-align: left;"&gt;
&lt;li&gt;run my batch file &lt;a href="http://bojan-komazec.blogspot.com/2011/10/nmake-and-its-environment.html#setenv.bat"&gt;&lt;b&gt;setenv.bat&lt;/b&gt;&lt;/a&gt; from the ..\axis2c-src-1.6.0\build\win32 directory providing "x64" as its argument&lt;/li&gt;
&lt;li&gt;go to "C:\Program Files\Microsoft Visual Studio 10.0\VC\bin\x86_amd64" and run &lt;b&gt;vcvarsx86_amd64.bat&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;go to "C:\Program Files\Microsoft Visual Studio 10.0\VC" and run&lt;b&gt; vcvarsall.bat&lt;/b&gt; providing "x86_amd64" as argument&lt;/li&gt;
&lt;/ul&gt;
After this, check whether nmake will use proper compiler and linker (x86_amd64 versions of&amp;nbsp;cl.exe&amp;nbsp;link.exe):&lt;br /&gt;
&lt;br /&gt;
&lt;div class="cmd_line"&gt;
C:\DEVELOPMENT\Toolkits\Axis2C\axis2c-src-1.6.0\build\win32&amp;gt;cd "C:\Program&lt;br /&gt;
Files\Microsoft Visual Studio 10.0\VC"&lt;br /&gt;
&lt;br /&gt;
C:\Program Files\Microsoft Visual Studio 10.0\VC&amp;gt;vcvarsall.bat x86_amd64&lt;br /&gt;
Setting environment for using Microsoft Visual Studio 2010 x64 cross tools.&lt;br /&gt;
&lt;br /&gt;
C:\Program Files\Microsoft Visual Studio 10.0\VC&amp;gt;goto :eof&lt;br /&gt;
&lt;br /&gt;
C:\Program Files\Microsoft Visual Studio 10.0\VC&amp;gt;cd "C:\DEVELOPMENT\Toolkits\Axi&lt;br /&gt;
s2C\axis2c-src-1.6.0\build\win32"&lt;br /&gt;
&lt;br /&gt;
C:\DEVELOPMENT\Toolkits\Axis2C\axis2c-src-1.6.0\build\win32&amp;gt;where nmake&lt;br /&gt;
c:\Program Files\Microsoft Visual Studio 10.0\VC\bin\nmake.exe&lt;br /&gt;
&lt;br /&gt;
C:\DEVELOPMENT\Toolkits\Axis2C\axis2c-src-1.6.0\build\win32&amp;gt;where cl&lt;br /&gt;
c:\Program Files\Microsoft Visual Studio 10.0\VC\bin\x86_amd64\cl.exe&lt;br /&gt;
c:\Program Files\Microsoft Visual Studio 10.0\VC\bin\cl.exe&lt;br /&gt;
&lt;br /&gt;
C:\DEVELOPMENT\Toolkits\Axis2C\axis2c-src-1.6.0\build\win32&amp;gt;where link&lt;br /&gt;
c:\Program Files\Microsoft Visual Studio 10.0\VC\bin\x86_amd64\link.exe&lt;br /&gt;
c:\Program Files\Microsoft Visual Studio 10.0\VC\bin\link.exe&lt;br /&gt;
&lt;br /&gt;
C:\DEVELOPMENT\Toolkits\Axis2C\axis2c-src-1.6.0\build\win32&amp;gt;&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Step 3:&lt;/span&gt;&lt;/b&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;Modify &lt;b&gt;configure.in&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
This file contains variables and flags for conditional compiling defined in makefile. If you don't need OpenSSL support, TCP server, using libxml2 (and so zlib1 and iconv), building Apache Axis2C engine module, libcurl, then modify configure.in to be like this:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="my_code"&gt;
#############################################################################&lt;br /&gt;
### Build Details ###&lt;br /&gt;
#############################################################################&lt;br /&gt;
#&lt;br /&gt;
# enables https support &lt;br /&gt;
ENABLE_SSL = 0          &lt;br /&gt;
#&lt;br /&gt;
# build libcurl transport &lt;br /&gt;
ENABLE_LIBCURL = 0&lt;br /&gt;
#&lt;br /&gt;
# build axis2 with Libxml2 Parser. Axis2/C will be built with embeded guththila # parser by Default. &lt;br /&gt;
ENABLE_LIBXML2=0&lt;br /&gt;
#&lt;br /&gt;
# build tcp server in addition to http server&lt;br /&gt;
WITH_TCP = 0&lt;br /&gt;
#&lt;br /&gt;
# build with archive based deployment&lt;br /&gt;
WITH_ARCHIVE = 0&lt;br /&gt;
#&lt;br /&gt;
#&lt;br /&gt;
#############################################################################&lt;br /&gt;
### Dependant Binary Locations (Required) ###&lt;br /&gt;
#############################################################################&lt;br /&gt;
#&lt;br /&gt;
# libxml2 binary location ( axis2c is built with libxml2 )&lt;br /&gt;
LIBXML2_BIN_DIR =&lt;br /&gt;
#&lt;br /&gt;
# iconv binary location&lt;br /&gt;
ICONV_BIN_DIR =&lt;br /&gt;
#&lt;br /&gt;
# zlib binary location&lt;br /&gt;
ZLIB_BIN_DIR=&lt;br /&gt;
#&lt;br /&gt;
#&lt;br /&gt;
#############################################################################&lt;br /&gt;
### Dependant Binary Locations (Optional) ###&lt;br /&gt;
#############################################################################&lt;br /&gt;
#&lt;br /&gt;
# openssl  binary location&lt;br /&gt;
# required if ENABLE_SSL = 1&lt;br /&gt;
OPENSSL_BIN_DIR =&lt;br /&gt;
#&lt;br /&gt;
# libcurl binary location, only required if libcurl transport is enabled&lt;br /&gt;
LIBCURL_BIN_DIR =&lt;br /&gt;
#&lt;br /&gt;
#&lt;br /&gt;
#############################################################################&lt;br /&gt;
### Apache Server module (required when building Axis2/C Apache Module) ###&lt;br /&gt;
#############################################################################&lt;br /&gt;
#&lt;br /&gt;
# apache binary location&lt;br /&gt;
APACHE_BIN_DIR = &lt;br /&gt;
#&lt;br /&gt;
# apache 2 server family&lt;br /&gt;
# To use apache 2.2 family, use  APACHE_VERSION_IS_2_0_X = 0&lt;br /&gt;
APACHE_VERSION_2_0_X = 0&lt;br /&gt;
#&lt;br /&gt;
#&lt;br /&gt;
#############################################################################&lt;br /&gt;
### Compiler Options ###&lt;br /&gt;
#############################################################################&lt;br /&gt;
#&lt;br /&gt;
# C runtime LIBRARY OPTION ( Use /MD or /MT )&lt;br /&gt;
CRUNTIME = /MT &lt;br /&gt;
#&lt;br /&gt;
# Embed Manifest Files&lt;br /&gt;
EMBED_MANIFEST = 1&lt;br /&gt;
#&lt;br /&gt;
# debug symbols&lt;br /&gt;
# To build with debug symbols use DEBUG = 1&lt;br /&gt;
DEBUG = 0&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: large;"&gt;Step 4:&lt;/span&gt;&lt;/b&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;Run NMAKE.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="cmd_line"&gt;
..\axis2c-src-1.6.0\build\win32&amp;gt;nmake install&lt;/div&gt;
&lt;br /&gt;
Build output is in directory &lt;b&gt;..\axis2c-src-1.6.0\build\deploy&lt;/b&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="file_hierarchy"&gt;
..\axis2c-src-1.6.0\build\deploy\&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;bin&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;docs&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;include&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;lib&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;logs&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;modules&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;samples&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;services&amp;nbsp; &lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;axis2.xml&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;...&lt;/div&gt;
&lt;br /&gt;
...and that's it! There is &lt;b&gt;NO &lt;/b&gt;need to change any compiler/linker options in makefile. Just make sure you've set NMAKE environment properly - so x86_amd64 versions of cl.exe and link.exe are used!&lt;br /&gt;
&lt;br /&gt;
You can check that all these&amp;nbsp;binaries are 64-bit by using&amp;nbsp;&lt;a href="http://www.dependencywalker.com/"&gt;Dependency Walker&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
NOTE 1: If you need to have different compiler/linker options in makefile, just add custom &lt;b&gt;BUILD_X86&lt;/b&gt; flag to &lt;b&gt;configure.in&lt;/b&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="my_code"&gt;
# BUILD_X86 = 1 if nmake should create x86 binaries.&lt;br /&gt;
# BUILD_X86 = 0 if nmake should create x64 (amd) binaries.&lt;br /&gt;
BUILD_X86 = 0&lt;/div&gt;
&lt;br /&gt;
&lt;b&gt;makefile &lt;/b&gt;can use this file to separate compiler/linker settings for 32 and 64-bit builds (I have defined some symbols here and set /MACHINE to X64 but THAT IS NOT NECESSARY - build succeeds even without these options!):&lt;br /&gt;
&lt;br /&gt;
&lt;div class="my_code"&gt;
...&lt;br /&gt;
...&lt;br /&gt;
&lt;span class="Apple-style-span" style="color: red;"&gt;!if "$(BUILD_X86)" == "1"&lt;/span&gt;&lt;br /&gt;
CFLAGS = /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AXIS2_DECLARE_EXPORT"  \&lt;br /&gt;
/D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_SECURE_NO_WARNINGS" \&lt;br /&gt;
/D "AXIS2_SVR_MULTI_THREADED" /W3 /wd4100  /MP10 /nologo $(AXIS2_INCLUDE_PATH) \&lt;br /&gt;
$(APACHE_INCLUDE_PATH)&lt;br /&gt;
&lt;span class="Apple-style-span" style="color: red;"&gt;!else&lt;/span&gt;&lt;br /&gt;
CFLAGS = /D "WIN32" &lt;span class="Apple-style-span" style="color: red;"&gt;/D "WIN64" /D "AMD64"&lt;/span&gt; /D "_WINDOWS" /D "_MBCS" /D "AXIS2_DECLARE_EXPORT"  \&lt;br /&gt;
/D "_CRT_SECURE_NO_DEPRECATE" /D "_CRT_SECURE_NO_WARNINGS" \&lt;br /&gt;
/D "AXIS2_SVR_MULTI_THREADED" /W3 /wd4100  /MP10 /nologo $(AXIS2_INCLUDE_PATH) \&lt;br /&gt;
$(APACHE_INCLUDE_PATH)&lt;br /&gt;
&lt;span class="Apple-style-span" style="color: red;"&gt;!endif&lt;/span&gt;&lt;br /&gt;
...&lt;br /&gt;
...&lt;br /&gt;
&lt;span class="Apple-style-span" style="color: red;"&gt;!if "$(BUILD_X86)" == "1"&lt;/span&gt;&lt;br /&gt;
LDFLAGS = /NOLOGO  /LIBPATH:$(AXIS2_LIBS) /LIBPATH:$(LIBXML2_BIN_DIR)\lib \&lt;br /&gt;
/LIBPATH:$(APACHE_BIN_DIR)\lib /LIBPATH:$(ZLIB_BIN_DIR)\lib&lt;br /&gt;
&lt;span class="Apple-style-span" style="color: red;"&gt;!else&lt;/span&gt;&lt;br /&gt;
LDFLAGS = /NOLOGO  /LIBPATH:$(AXIS2_LIBS) /LIBPATH:$(LIBXML2_BIN_DIR)\lib \&lt;br /&gt;
/LIBPATH:$(APACHE_BIN_DIR)\lib /LIBPATH:$(ZLIB_BIN_DIR)\lib  &lt;span class="Apple-style-span" style="color: red;"&gt;/MACHINE:X64&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="color: red;"&gt;!endif&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
NOTE 2: If you need to build 64-bit Axis2C for deploying it as IIS module add this target to makefile:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="my_code"&gt;
iis_deploy: deploy axis2_core_without_server axis2_IIS_module copy_axis2_xml&lt;/div&gt;
&lt;br /&gt;
and call nmake with it:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="cmd_line"&gt;
..\axis2c-src-1.6.0\build\win32&amp;gt;nmake iis_deploy&lt;/div&gt;
&lt;br /&gt;
Your web service dll must be built for 64-bit Windows as well and must be built against 64-bit Axis2/C libraries.&lt;br /&gt;
&lt;br /&gt;
Links and references:&lt;br /&gt;
&lt;a href="http://axis.apache.org/axis2/c/core/docs/installationguide.html"&gt;Apache Axis2/C Installation Guide&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/x4d2c09s.aspx"&gt;How to: Enable a 64-Bit Visual C++ Toolset at the Command Line&lt;/a&gt;&lt;/div&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4912226416400969049-4407765391420011873?l=bojan-komazec.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/YJTOWgogrv5CqO4KUOPU1NCJ8Gg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/YJTOWgogrv5CqO4KUOPU1NCJ8Gg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/YJTOWgogrv5CqO4KUOPU1NCJ8Gg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/YJTOWgogrv5CqO4KUOPU1NCJ8Gg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/MyPublicNotepad/~4/HhSiLM_-RNA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://bojan-komazec.blogspot.com/feeds/4407765391420011873/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4912226416400969049&amp;postID=4407765391420011873" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/4407765391420011873?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/4407765391420011873?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyPublicNotepad/~3/HhSiLM_-RNA/how-to-build-axis2c-for-64-bit-windows.html" title="How to build Axis2C for 64-bit Windows" /><author><name>Bojan Komazec</name><uri>https://profiles.google.com/117174187628268281803</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://bojan-komazec.blogspot.com/2011/10/how-to-build-axis2c-for-64-bit-windows.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEEFRn4zeCp7ImA9WhdUGUQ.&quot;"><id>tag:blogger.com,1999:blog-4912226416400969049.post-46312569891865476</id><published>2011-10-06T19:05:00.000+01:00</published><updated>2011-10-07T15:10:17.080+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-07T15:10:17.080+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Windows" /><category scheme="http://www.blogger.com/atom/ns#" term="Computer architecture" /><category scheme="http://www.blogger.com/atom/ns#" term="Visual Studio" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><title>32-bit and 64-bit versions of Windows C++ application</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;How to set compiler and linker options in order to build some C++ application for 64-bit Windows? Sample application I will test this on is one that detects two things that should not be mixed:&lt;br /&gt;
&lt;ul style="text-align: left;"&gt;&lt;li&gt;detecting which processor architecture application has been compiled for (performed in compile time)&lt;/li&gt;
&lt;li&gt;detecting which processor architecture application is running on (performed in run-time)&lt;/li&gt;
&lt;/ul&gt;There is no portable way of performing these checks.&lt;br /&gt;
&lt;br /&gt;
Compiler's target architecture can be detected by checking which &lt;a href="http://msdn.microsoft.com/en-us/library/b0084kay.aspx"&gt;pre-defined symbols (macros)&lt;/a&gt; have automatically been defined by compiler (this is compiler specific! - different compilers use different macros). Some Microsoft-specific are: &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;_WIN32&lt;/b&gt; - defined for applications for Win32 and Win64. Always defined.&lt;br /&gt;
&lt;b&gt;_WIN64&lt;/b&gt; - defined for applications for Win64.&lt;br /&gt;
&lt;b&gt;_M_AMD64&lt;/b&gt; - defined for x64 processors&lt;br /&gt;
&lt;b&gt;_M_X64&lt;/b&gt; - defined for x64 processors&lt;br /&gt;
&lt;b&gt;_M_IX86&lt;/b&gt; - defined for x86 processors&lt;br /&gt;
&lt;b&gt;_M_IA64&lt;/b&gt; - defined for Itanium Processor Family 64-bit processors&lt;br /&gt;
&lt;br /&gt;
These macros determine target processor - one that we are building application for (not processor we are building on). We don't need to add them manually as&amp;nbsp;compiler will define them: _WIN32 and _M_IX86 for 32-bit applications and _WIN64, _M_AMD64, _M_X64 and _M_IA64 for 64-bit ones.&lt;br /&gt;
&lt;br /&gt;
Another test can be checking the value of the &lt;b&gt;sizeof(void*)&lt;/b&gt;. It is 4 bytes in applications compiled for 32-bit architectures and 8 bytes in 64-bit applications, regardless on the processor architecture application is running on.&lt;br /&gt;
&lt;br /&gt;
Host's processor architecture can be obtained in run-time in various ways, of which some of them (on Windows) are:&lt;br /&gt;
&lt;ul style="text-align: left;"&gt;&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/hskdteyh.aspx"&gt;&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: Consolas, Courier, monospace; font-size: 13px; white-space: pre;"&gt;__cpuid&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;check PROCESSOR_ARCHITECTURE and PROCESSOR_ARCHITEW6432 environment variables (or&amp;nbsp;read value of PROCESSOR_ARCHITECTURE in registry on path HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment)&lt;/li&gt;
&lt;li&gt;Use &lt;a href="http://msdn.microsoft.com/en-us/library/ms724381%28VS.85%29.aspx"&gt;GetSystemInfo()&lt;/a&gt; or &lt;a href="http://msdn.microsoft.com/en-us/library/ms724340%28VS.85%29.aspx"&gt;GetNativeSystemInfo()&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;main.cpp uses methods described above:&lt;br /&gt;
&lt;br /&gt;
&lt;div dir="ltr" trbidi="on"&gt;&lt;div class="my_code"&gt;#include &amp;lt;windows.h&amp;gt;&lt;br /&gt;
#include  &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt;&lt;br /&gt;
#include &amp;lt;intrin.h&amp;gt;&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
void CheckIs64BitAvailable()&lt;br /&gt;
{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;bool b64Available = false;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;int CPUInfo[4] = {0};&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; __cpuid(CPUInfo, 0);&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; b64Available = (CPUInfo[3] &amp;amp; 0x20000000) || false;&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;if(b64Available)&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;cout &amp;lt;&amp;lt; "64-bit processor" &amp;lt;&amp;lt; endl;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;}&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;else&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;cout &amp;lt;&amp;lt; "32-bit processor" &amp;lt;&amp;lt; endl;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void CheckNativeSystemProcessorArchitecture()&lt;br /&gt;
{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;SYSTEM_INFO si;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;memset(&amp;amp;si, 0, sizeof(si));&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;GetNativeSystemInfo(&amp;amp;si);&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;switch(si.wProcessorArchitecture)&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;case PROCESSOR_ARCHITECTURE_AMD64:&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;cout &amp;lt;&amp;lt; "PROCESSOR_ARCHITECTURE_AMD64 - x64 (AMD or Intel)" &amp;lt;&amp;lt; endl;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;break;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;case PROCESSOR_ARCHITECTURE_IA64:&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;cout &amp;lt;&amp;lt; "PROCESSOR_ARCHITECTURE_IA64 - Intel Itanium-based" &amp;lt;&amp;lt; endl;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;break;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;case PROCESSOR_ARCHITECTURE_INTEL:&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;cout &amp;lt;&amp;lt; "PROCESSOR_ARCHITECTURE_INTEL - x86" &amp;lt;&amp;lt; endl;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;break;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;case PROCESSOR_ARCHITECTURE_UNKNOWN:&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;cout &amp;lt;&amp;lt; "PROCESSOR_ARCHITECTURE_UNKNOWN - Unknown architecture" &amp;lt;&amp;lt; endl;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;break;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void CheckSystemProcessorArchitecture()&lt;br /&gt;
{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;cout &amp;lt;&amp;lt; "Calling GetSystemInfo()..." &amp;lt;&amp;lt; endl;&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;SYSTEM_INFO si;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;memset(&amp;amp;si, 0, sizeof(si));&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;GetSystemInfo(&amp;amp;si);&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;switch(si.wProcessorArchitecture)&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;case PROCESSOR_ARCHITECTURE_AMD64:&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;cout &amp;lt;&amp;lt; "PROCESSOR_ARCHITECTURE_AMD64 - x64 (AMD or Intel)" &amp;lt;&amp;lt; endl;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;break;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;case PROCESSOR_ARCHITECTURE_IA64:&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;cout &amp;lt;&amp;lt; "PROCESSOR_ARCHITECTURE_IA64 - Intel Itanium-based" &amp;lt;&amp;lt; endl;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;break;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;case PROCESSOR_ARCHITECTURE_INTEL:&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;cout &amp;lt;&amp;lt; "PROCESSOR_ARCHITECTURE_INTEL - x86" &amp;lt;&amp;lt; endl;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;break;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;case PROCESSOR_ARCHITECTURE_UNKNOWN:&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;cout &amp;lt;&amp;lt; "PROCESSOR_ARCHITECTURE_UNKNOWN - Unknown architecture" &amp;lt;&amp;lt; endl;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;break;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void CheckEnvVariable_PROCESSOR_ARCHITECTURE()&lt;br /&gt;
{&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;char* pszProcArch = getenv("PROCESSOR_ARCHITECTURE");&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;if(pszProcArch)&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;cout &amp;lt;&amp;lt; "PROCESSOR_ARCHITECTURE (environment variable): " &amp;lt;&amp;lt; string(pszProcArch) &amp;lt;&amp;lt; endl;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;}&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;else&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;cout &amp;lt;&amp;lt; "PROCESSOR_ARCHITECTURE (environment variable) not found" &amp;lt;&amp;lt; endl;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void CheckEnvVariable_PROCESSOR_ARCHITEW6432()&lt;br /&gt;
{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;// PROCESSOR_ARCHITEW6432 is defined only in WoW64 where reports the original native processor architecture&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;char* pszProcArch = getenv("PROCESSOR_ARCHITEW6432");&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;if(pszProcArch)&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;cout &amp;lt;&amp;lt; "PROCESSOR_ARCHITEW6432 (environment variable): " &amp;lt;&amp;lt; string(pszProcArch) &amp;lt;&amp;lt; endl;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;}&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;else&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;cout &amp;lt;&amp;lt; "PROCESSOR_ARCHITEW6432 (environment variable) not found" &amp;lt;&amp;lt; endl;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void CheckRegVal_PROCESSOR_ARCHITECTURE()&lt;br /&gt;
{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;HKEY hKey;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;DWORD dwBuffSize = 1023;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;DWORD dwType;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;char szValue[1024] = {0};&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;LONG lErrorCode = RegOpenKeyEx(&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;HKEY_LOCAL_MACHINE,&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment",&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;0,&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;KEY_QUERY_VALUE,&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;&amp;amp;hKey);&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;if(lErrorCode!= ERROR_SUCCESS)&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;cout &amp;lt;&amp;lt; "RegOpenKeyEx() failed. Error: " &amp;lt;&amp;lt; lErrorCode &amp;lt;&amp;lt; endl;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;return;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;}&lt;br /&gt;
&amp;nbsp; &lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;RegQueryValueEx(&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;			&lt;/span&gt;hKey,&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;			&lt;/span&gt;"PROCESSOR_ARCHITECTURE",&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;			&lt;/span&gt;NULL,&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;			&lt;/span&gt;&amp;amp;dwType,&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;			&lt;/span&gt;(LPBYTE)szValue,&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;			&lt;/span&gt;&amp;amp;dwBuffSize);&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;cout &amp;lt;&amp;lt; "PROCESSOR_ARCHITECTURE (registry value): " &amp;lt;&amp;lt; string(szValue) &amp;lt;&amp;lt; endl;&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;RegCloseKey(hKey); &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;cout &amp;lt;&amp;lt; "sizeof(void*) = " &amp;lt;&amp;lt; sizeof(void*) &amp;lt;&amp;lt; " [bytes]"&amp;lt;&amp;lt; endl;&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;CheckIs64BitAvailable();&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;CheckRegVal_PROCESSOR_ARCHITECTURE();&lt;br /&gt;
&lt;br /&gt;
// Defined for applications for Win32 and Win64. Always defined.&lt;br /&gt;
#ifdef _WIN32&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;cout &amp;lt;&amp;lt; "_WIN32 defined" &amp;lt;&amp;lt; endl;&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// _WIN64 is defined for applications for Win64 (they can run only on Win64)&lt;br /&gt;
#ifdef _WIN64&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;cout &amp;lt;&amp;lt; "_WIN64 defined =&amp;gt; target architecture is Win64; Process is running on native Win64" &amp;lt;&amp;lt; endl;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;CheckSystemProcessorArchitecture();&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;CheckEnvVariable_PROCESSOR_ARCHITECTURE();&lt;br /&gt;
#else&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;cout &amp;lt;&amp;lt; "_WIN64 is not defined =&amp;gt; target architecture is Win32" &amp;lt;&amp;lt; endl;&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;BOOL bIs64 = FALSE;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;IsWow64Process(GetCurrentProcess(), &amp;amp;bIs64);&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;if(bIs64)&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;cout &amp;lt;&amp;lt; "Process is running under WoW64" &amp;lt;&amp;lt; endl;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;CheckNativeSystemProcessorArchitecture();&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;CheckEnvVariable_PROCESSOR_ARCHITEW6432();&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;}&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;else&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;{&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;cout &amp;lt;&amp;lt; "Process is running on Win32" &amp;lt;&amp;lt; endl;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;CheckSystemProcessorArchitecture();&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;		&lt;/span&gt;CheckEnvVariable_PROCESSOR_ARCHITECTURE();&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;}&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// WIN32 is defined outside compiler - by the SDK or the build environment&lt;br /&gt;
#ifdef WIN32&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;cout &amp;lt;&amp;lt; "WIN32 defined" &amp;lt;&amp;lt; endl;&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// WIN64 is defined outside compiler - by the SDK or the build environment&lt;br /&gt;
#ifdef WIN64&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;cout &amp;lt;&amp;lt; "WIN64 defined" &amp;lt;&amp;lt; endl;&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Pre-defined Architecture Macro: Intel x86; Defined for x86 processors&lt;br /&gt;
#ifdef _M_IX86&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;cout &amp;lt;&amp;lt; "_M_IX86 defined: " &amp;lt;&amp;lt; _M_IX86 &amp;lt;&amp;lt; endl;&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Pre-defined Architecture Macro: AMD64; Defined for x64 processors.&lt;br /&gt;
#ifdef _M_X64&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;cout &amp;lt;&amp;lt; "_M_X64 defined: " &amp;lt;&amp;lt; _M_X64 &amp;lt;&amp;lt; endl;&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Defined for x64 processors.&lt;br /&gt;
#ifdef _M_AMD64&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;cout &amp;lt;&amp;lt; "_M_AMD64 defined: " &amp;lt;&amp;lt; _M_AMD64 &amp;lt;&amp;lt; endl;&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
// Pre-defined Architecture Macro: Intel Architecture-64 (Defined for Itanium Processor Family 64-bit processors.)&lt;br /&gt;
#ifdef _M_IA64&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;cout &amp;lt;&amp;lt; "_M_IA64 defined: " &amp;lt;&amp;lt; _M_IA64 &amp;lt;&amp;lt; endl;&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;return 0;&lt;br /&gt;
}&lt;/div&gt;&lt;br /&gt;
This is application's output when run on 32-bit Windows (Win 7):&lt;br /&gt;
&lt;div class="cmd_line"&gt;..\Release&amp;gt;ProcArchTest_x86.exe&lt;br /&gt;
sizeof(void*) = 4 [bytes]&lt;br /&gt;
32-bit processor&lt;br /&gt;
PROCESSOR_ARCHITECTURE (registry value): x86&lt;br /&gt;
_WIN32 defined&lt;br /&gt;
_WIN64 is not defined =&amp;gt; target architecture is Win32&lt;br /&gt;
Process is running on Win32&lt;br /&gt;
Calling GetSystemInfo()...&lt;br /&gt;
PROCESSOR_ARCHITECTURE_INTEL - x86&lt;br /&gt;
PROCESSOR_ARCHITECTURE (environment variable): x86&lt;br /&gt;
WIN32 defined&lt;br /&gt;
_M_IX86 defined: 600&lt;br /&gt;
&lt;br /&gt;
C:\DEVELOPMENT\RESEARCH\C++\ProcessorBitTest\Release&amp;gt;&lt;/div&gt;&lt;br /&gt;
This is application's output when run on 64-bit Windows (Win 7 emulated on VirtualBox):&lt;br /&gt;
&lt;div class="cmd_line"&gt;C:\Users\Bojan\Desktop&amp;gt;ProcArchTest_x86.exe&lt;br /&gt;
sizeof(void*) = 4 [bytes]&lt;br /&gt;
32-bit processor&lt;br /&gt;
PROCESSOR_ARCHITECTURE (registry value): AMD64&lt;br /&gt;
_WIN32 defined&lt;br /&gt;
_WIN64 is not defined =&amp;gt; target architecture is Win32&lt;br /&gt;
Process is running under WoW64&lt;br /&gt;
PROCESSOR_ARCHITECTURE_AMD64 - x64 (AMD or Intel)&lt;br /&gt;
PROCESSOR_ARCHITEW6432 (environment variable): AMD64&lt;br /&gt;
WIN32 defined&lt;br /&gt;
_M_IX86 defined: 600&lt;br /&gt;
&lt;br /&gt;
C:\Users\Bojan\Desktop&amp;gt;&lt;/div&gt;&lt;br /&gt;
Now, let us build this application for 64-bit Windows. In Visual Studio, we need to create a new build platform: Build -&amp;gt; Configuration Manager -&amp;gt; Active Solution Platform, New; select "x64" and copy settings from Win32. &lt;br /&gt;
&lt;br /&gt;
Let us compare compiler options for 32-bit and 64-bit Release configurations in order to see what are the differences:&lt;br /&gt;
&lt;br /&gt;
Compiler options for Win32 Release:&lt;br /&gt;
&lt;div class="file_hierarchy"&gt;/Zi /nologo /W3 /WX- /O2 /Oi &lt;span class="Apple-style-span" style="color: red;"&gt;/Oy-&lt;/span&gt; /GL /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /Gm- /EHsc /MT /GS /Gy /fp:precise /Zc:wchar_t /Zc:forScope /Fp"Release\ProcArchTest_x86.pch" /Fa"Release\" /Fo"Release\" /Fd"Release\vc100.pdb" /Gd &lt;span class="Apple-style-span" style="color: red;"&gt;/analyze-&lt;/span&gt; /errorReport:queue&lt;/div&gt;&lt;br /&gt;
Compiler options for x64 Release:&lt;br /&gt;
&lt;div class="file_hierarchy"&gt;/Zi /nologo /W3 /WX- /O2 /Oi /GL /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /Gm- /EHsc /MT /GS /Gy /fp:precise /Zc:wchar_t /Zc:forScope /Fp"x64\Release\ProcArchTest_x64.pch" /Fa"x64\Release\" /Fo"x64\Release\" /Fd"x64\Release\vc100.pdb" /Gd /errorReport:queue&lt;/div&gt;&lt;br /&gt;
We can see that all options are the same except in case of /Oy and /analyze which are available only for x86 compilers.&lt;br /&gt;
&lt;br /&gt;
What about linker options?&lt;br /&gt;
&lt;br /&gt;
Linker options for Win32 Release:&lt;br /&gt;
&lt;div class="file_hierarchy"&gt;/OUT:"..\Release\ProcArchTest_x86.exe"     /INCREMENTAL:NO /NOLOGO "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /MANIFEST /ManifestFile:"Release\ProcArchTest_x86.exe.intermediate.manifest"     /ALLOWISOLATION /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"..\ProcessorBitTest\Release\ProcArchTest_x86.pdb" /SUBSYSTEM:CONSOLE /OPT:REF /OPT:ICF /PGD:"..\ProcessorBitTest\Release\ProcArchTest_x86.pgd" /LTCG /TLBID:1 /DYNAMICBASE /NXCOMPAT &lt;span class="Apple-style-span" style="color: red;"&gt;/MACHINE:X86&lt;/span&gt; /ERRORREPORT:QUEUE&lt;/div&gt;&lt;br /&gt;
Linker options for x64 Release:&lt;br /&gt;
&lt;div class="file_hierarchy"&gt;/OUT:"..\x64\Release\ProcArchTest_x64.exe" /INCREMENTAL:NO /NOLOGO "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /MANIFEST /ManifestFile:"x64\Release\ProcArchTest_x64.exe.intermediate.manifest" /ALLOWISOLATION /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"..\ProcessorBitTest\x64\Release\ProcArchTest_x64.pdb" /SUBSYSTEM:CONSOLE /OPT:REF /OPT:ICF /PGD:"..\ProcessorBitTest\x64\Release\ProcArchTest_x64.pgd" /LTCG /TLBID:1 /DYNAMICBASE /NXCOMPAT &lt;span class="Apple-style-span" style="color: red;"&gt;/MACHINE:X64&lt;/span&gt; /ERRORREPORT:QUEUE&lt;/div&gt;&lt;br /&gt;
We can see that linker options differ only in the value of /MACHINE option. &lt;br /&gt;
&lt;br /&gt;
&lt;div class="black_border"&gt;NOTE: /MACHINE option does not need to be set at all! Compiler inserts information about target architecture in OBJ files' headers. OBJ files created with Microsoft compiler have PE/COFF format which is described in &lt;a href="http://msdn.microsoft.com/en-us/library/ms680547(v=VS.85).aspx"&gt;Microsoft PE and COFF Specification&lt;/a&gt;. At the beginning of an object file, or immediately after the signature of an image file, is a standard COFF file header. Its first field is "Machine" whose value is the number that identifies the type of target machine (CPU type). Some values are: IMAGE_FILE_MACHINE_AMD64 (x64), IMAGE_FILE_MACHINE_I386 (Intel 386 or later processors and compatible processors - x86), IMAGE_FILE_MACHINE_IA64 (Intel Itanium processor family). &lt;a href="http://msdn.microsoft.com/en-us/library/5wy54dk2.aspx"&gt;Linker reads that information&lt;/a&gt;. If you compile your app with $(VCInstallDir)bin\x86_amd64\cl.exe linker will create amd64 binary even with /MACHINE Not Set! Cross-compiling with Microsoft (Visual Studio) tools is all about using correct compiler and linker! Compiler and linker options can actually be same for both 32-bit and 64-bit builds! When building 64-bit application in Visual Studio, just make sure that Executable Directories has (cl.exe and link.exe) paths in this order $(VCInstallDir)bin\x86_amd64;$(VCInstallDir)bin; and that AMD paths are listed first in Include and Library Directories (but all this should be done automatically upon creation of x64 project!).&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
Let us continue with analysis.&lt;br /&gt;
&lt;br /&gt;
Although names of some libraries end with "32" for both x86 and x64 configurations, their different (32-bit or 64-bit) versions are actually used in different builds. Same for the compiler and linker - please read my article &lt;a href="http://bojan-komazec.blogspot.com/2011/10/nmake-and-its-environment.html"&gt;"NMAKE and its environment"&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Let us try to run now our 64-bit application on 32-bit Windows OS:&lt;br /&gt;
&lt;div class="cmd_line"&gt;..\x64\Release&amp;gt;ProcArchTest_x64.exe&lt;br /&gt;
This version of ..\x64\Release\ProcArchTest_x64.exe is not compatible with the &lt;br /&gt;
version of Windows you're running. Check your computer's system information&lt;br /&gt;
to see whether you need a x86 (32-bit) or x64 (64-bit) version of the program, &lt;br /&gt;
and then contact the software publisher.&lt;br /&gt;
&lt;br /&gt;
C:\DEVELOPMENT\RESEARCH\C++\ProcessorBitTest\x64\Release&amp;gt;&lt;/div&gt;&lt;br /&gt;
This was expected as 64-bit application cannot run on 32-bit operating systems.&lt;br /&gt;
What about running it in its natural, 64-bit, enviroment - on 64-bit OS?&lt;br /&gt;
&lt;br /&gt;
&lt;div class="cmd_line"&gt;C:\Users\Bojan\Desktop&amp;gt;ProcArchTest_x64.exe&lt;br /&gt;
sizeof(void*) = 8 [bytes]&lt;br /&gt;
32-bit processor&lt;br /&gt;
PROCESSOR_ARCHITECTURE (registry value): AMD64&lt;br /&gt;
_WIN32 defined&lt;br /&gt;
_WIN64 defined =&amp;gt; target architecture is Win64; Process is running on native Win&lt;br /&gt;
64&lt;br /&gt;
Calling GetSystemInfo()...&lt;br /&gt;
PROCESSOR_ARCHITECTURE_AMD64 - x64 (AMD or Intel)&lt;br /&gt;
PROCESSOR_ARCHITECTURE (environment variable): AMD64&lt;br /&gt;
WIN32 defined&lt;br /&gt;
_M_X64 defined: 100&lt;br /&gt;
_M_AMD64 defined: 100&lt;br /&gt;
&lt;br /&gt;
C:\Users\Bojan\Desktop&amp;gt;&lt;/div&gt;&lt;br /&gt;
Conclusion: &lt;br /&gt;
&lt;ul style="text-align: left;"&gt;&lt;li&gt;application targets 64-bit architecture if _WIN64, _M_X64 and/or _M_AMD64 are defined and/or if sizeof(void*) is 8&lt;/li&gt;
&lt;li&gt;reliable way of getting the architecture of the host processor in runtime is reading PROCESSOR_ARCHITECTURE value from registry or using GetSystemInfo()/GetNativeSystemInfo()&lt;/li&gt;
&lt;/ul&gt;Advice:&lt;br /&gt;
Don't rely on WoW64 as it might not be enabled/installed on the target machine (e.g. WoW64 is optional on Windows Server 2003 R2). WoW64 is intended to support legacy 32-bit applications anyway. Build new applications for both x86 and x64 architectures. This way you can avoid some potential errors in applications that can occur due to directory and registry redirections under WoW64.&lt;br /&gt;
&lt;br /&gt;
Links and references:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms684139(v=vs.85).aspx"&gt;IsWow64Process function&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/64-bit"&gt;64-bit (Wikipedia)&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/WoW64"&gt;WoW64 (Wikipedia)&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://blogs.msdn.com/b/tolong/archive/2007/03/21/use-visual-studio-to-build-64-bit-application.aspx"&gt;Use Visual Studio to build 64-bit application (MSDN blog)&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://msdn.microsoft.com/en-us/magazine/cc300794.aspx"&gt;Everything You Need To Know To Start Programming 64-Bit Windows Systems&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/ms241066.aspx"&gt;Visual Studio Development Environment 64-Bit Support&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://blogs.msdn.com/b/david.wang/archive/2006/03/26/howto-detect-process-bitness.aspx"&gt;HOWTO: Detect Process Bitness&lt;/a&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/ms185328.aspx"&gt;How to: Configure Projects to Target Platforms (MSDN)&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/9yb4317s.aspx"&gt;How to: Configure Visual C++ Projects to Target 64-Bit Platforms (MSDN)&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://support.microsoft.com/kb/827218"&gt;How to determine whether a computer is running a 32-bit version or 64-bit version of the Windows operating system (MSDN)&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/b0084kay.aspx"&gt;Predefined Macros (MSDN)&lt;/a&gt;&lt;/div&gt;&lt;a href="http://blogs.msdn.com/b/oldnewthing/archive/2006/09/06/742710.aspx"&gt;You already know what your target architecture is (or at least you should)&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://blogs.msdn.com/b/oldnewthing/archive/2005/02/01/364563.aspx"&gt;How to detect programmatically whether you are running on 64-bit Windows&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://stackoverflow.com/questions/152016/detecting-cpu-architecture-compile-time"&gt;Detecting CPU architecture compile-time&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://stackoverflow.com/questions/1636950/detect-system-architecture-x86-x64-while-running"&gt;Detect system architecture (x86/x64) while running&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://stackoverflow.com/questions/735647/ifdef-for-32-bit-platform/735656#735656"&gt;#ifdef for 32-bit platform&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://stackoverflow.com/questions/191873/determining-64-bit-vs-32-bit-windows"&gt;Determining 64-bit vs. 32-bit Windows&lt;/a&gt;&lt;/div&gt;&lt;a href="http://blogs.msdn.com/b/tolong/archive/2007/03/21/use-visual-studio-to-build-64-bit-application.aspx"&gt;Use Visual Studio to build 64-bit application&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.viva64.com/en/a/0042/"&gt;Seven Steps of Migrating a Program to a 64-bit System&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4912226416400969049-46312569891865476?l=bojan-komazec.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/0VqKXZeNuPLhJSnxaZ-M8U8zq3o/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/0VqKXZeNuPLhJSnxaZ-M8U8zq3o/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/0VqKXZeNuPLhJSnxaZ-M8U8zq3o/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/0VqKXZeNuPLhJSnxaZ-M8U8zq3o/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/MyPublicNotepad/~4/KbBLUnKL6Xg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://bojan-komazec.blogspot.com/feeds/46312569891865476/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4912226416400969049&amp;postID=46312569891865476" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/46312569891865476?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/46312569891865476?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyPublicNotepad/~3/KbBLUnKL6Xg/32-bit-and-64-bit-versions-of-windows-c.html" title="32-bit and 64-bit versions of Windows C++ application" /><author><name>Bojan Komazec</name><uri>https://profiles.google.com/117174187628268281803</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://bojan-komazec.blogspot.com/2011/10/32-bit-and-64-bit-versions-of-windows-c.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEMMRX4_fCp7ImA9WhdUGE4.&quot;"><id>tag:blogger.com,1999:blog-4912226416400969049.post-3001767267149329863</id><published>2011-10-05T17:21:00.000+01:00</published><updated>2011-10-05T18:41:24.044+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-05T18:41:24.044+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="makefile" /><category scheme="http://www.blogger.com/atom/ns#" term="manipulator" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><category scheme="http://www.blogger.com/atom/ns#" term="NMAKE" /><title>How to use nmake and makefile</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;
Let's build simple "Hello, world!" application from command line by using Microsoft's &lt;b&gt;nmake&lt;/b&gt;. Necessary steps are:&lt;br /&gt;
&lt;br /&gt;
1) create project directory ("..\HelloWorld")&lt;br /&gt;
2) create source file ("..\HelloWorld\main.cpp")&lt;br /&gt;
3) create makefile ("..\HelloWorld\makefile")&lt;br /&gt;
4) set up environment (environment variables) for nmake. I will use my setenv.bat script from my post "&lt;a href="http://bojan-komazec.blogspot.com/2011/10/nmake-and-its-environment.html"&gt;NMAKE and its environment&lt;/a&gt;" (run "..\HelloWorld\setenv.bat" with &amp;nbsp;&amp;nbsp;&amp;nbsp;"x86" argument)&lt;br /&gt;
5) run nmake&lt;br /&gt;
&lt;br /&gt;
main.cpp:
&lt;br /&gt;
&lt;div class="my_code"&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp;  std::cout &amp;lt;&amp;lt; "Hello, world!" &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
&amp;nbsp;  return 0;&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
The shortest version of makefile needs to contain at least one &lt;a href="http://msdn.microsoft.com/en-us/library/fb7966ta.aspx"&gt;description block&lt;/a&gt;:
 &lt;br /&gt;
&lt;div class="file_hierarchy"&gt;
target : dependencies&lt;br /&gt;
&amp;nbsp;commands
&lt;/div&gt;
&lt;br /&gt;
makefile:
&lt;br /&gt;
&lt;div class="my_code"&gt;
foo: main.cpp&lt;br /&gt;
&amp;nbsp;cl main.cpp
&lt;/div&gt;
&lt;br /&gt;
Here's the order of commands in the command prompt window:
&lt;br /&gt;
&lt;div class="cmd_line"&gt;
&lt;br /&gt;
C:\DEVELOPMENT\RESEARCH\C++\HelloWorld&amp;gt;setenv x86&lt;br /&gt;
Setting environment for using Microsoft Visual Studio 2010 x86 tools.&lt;br /&gt;
&lt;br /&gt;
C:\DEVELOPMENT\RESEARCH\C++\HelloWorld&amp;gt;where nmake&lt;br /&gt;
c:\Program Files\Microsoft Visual Studio 10.0\VC\bin\nmake.exe&lt;br /&gt;
&lt;br /&gt;
C:\DEVELOPMENT\RESEARCH\C++\HelloWorld&amp;gt;where cl.exe&lt;br /&gt;
c:\Program Files\Microsoft Visual Studio 10.0\VC\bin\cl.exe&lt;br /&gt;
&lt;br /&gt;
C:\DEVELOPMENT\RESEARCH\C++\HelloWorld&amp;gt;where link.exe&lt;br /&gt;
c:\Program Files\Microsoft Visual Studio 10.0\VC\bin\link.exe&lt;br /&gt;
&lt;br /&gt;
C:\DEVELOPMENT\RESEARCH\C++\HelloWorld&amp;gt;nmake&lt;br /&gt;
&lt;br /&gt;
Microsoft (R) Program Maintenance Utility Version 10.00.30319.01&lt;br /&gt;
Copyright (C) Microsoft Corporation. &amp;nbsp;All rights reserved.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cl main.cpp&lt;br /&gt;
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.30319.01 for 80x86&lt;br /&gt;
Copyright (C) Microsoft Corporation. &amp;nbsp;All rights reserved.&lt;br /&gt;
&lt;br /&gt;
main.cpp&lt;br /&gt;
c:\Program Files\Microsoft Visual Studio 10.0\VC\include\xlocale(323) : warning&lt;br /&gt;
C4530: C++ exception handler used, but unwind semantics are not enabled. Specify&lt;br /&gt;
&amp;nbsp;/EHsc&lt;br /&gt;
Microsoft (R) Incremental Linker Version 10.00.30319.01&lt;br /&gt;
Copyright (C) Microsoft Corporation. &amp;nbsp;All rights reserved.&lt;br /&gt;
&lt;br /&gt;
/out:main.exe&lt;br /&gt;
main.obj&lt;br /&gt;
&lt;br /&gt;
C:\DEVELOPMENT\RESEARCH\C++\HelloWorld&amp;gt;main&lt;br /&gt;
Hello, world!&lt;br /&gt;
&lt;br /&gt;
C:\DEVELOPMENT\RESEARCH\C++\HelloWorld&amp;gt;&lt;/div&gt;
&lt;br /&gt;
Compiler creates obj file and automatically invokes the linker after compiling unless the &lt;b&gt;/c&lt;/b&gt; option is used. Linker creates executable. Upon nmake call, we have following files in our project directory:
&lt;br /&gt;
&lt;div class="file_hierarchy"&gt;
..\HelloWorld\main.cpp&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; main.exe&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; main.obj&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; makefile&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; setenv.bat
&lt;/div&gt;
&lt;br /&gt;
Ok, we got binary but let us tidy things a bit and let us see how to involve header files. By default, compiler gives binary a default name using the base name of the first source or object file specified on the command line. I want binary to be named as "helloworld.exe" and want it to be placed in "..\HelloWorld\bin\x86" directory. OBJ files should be put in the intermediate directory "..\HelloWorld\intermediate\x86". I want my main function to be in "..\HelloWorld\src\main.cpp" and to use some function declared in header "..\HelloWorld\include\printx.h" and defined in "..\HelloWorld\src\printx.cpp". Furthermore, makefile should be in "..\HelloWorld\build". Project structure before nmake call should be:
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="file_hierarchy"&gt;
..\HelloWorld\src\main.cpp&lt;br /&gt;
..\HelloWorld\src\printx.cpp&lt;br /&gt;
..\HelloWorld\include\printx.h&lt;br /&gt;
..\HelloWorld\build\makefile&lt;br /&gt;
..\HelloWorld\build\setenv.bat&lt;/div&gt;
&lt;br /&gt;
And after nmake call:
&lt;br /&gt;
&lt;div class="file_hierarchy"&gt;
..\HelloWorld\src\main.cpp&lt;br /&gt;
..\HelloWorld\src\printx.cpp&lt;br /&gt;
..\HelloWorld\include\printx.h&lt;br /&gt;
..\HelloWorld\build\makefile&lt;br /&gt;
..\HelloWorld\build\setenv.bat&lt;br /&gt;
..\HelloWorld\intermediate\x86\main.obj&lt;br /&gt;
..\HelloWorld\intermediate\x86\printx.obj&lt;br /&gt;
..\HelloWorld\bin\x86\helloworld.exe
&lt;/div&gt;
&lt;br /&gt;
Let us assume that new unit in our project, printx, contains implementation of our custom manipulator which inserts given number of asterisks into output stream. 
&lt;br /&gt;
&lt;br /&gt;
printx.h:
&lt;br /&gt;
&lt;div class="my_code"&gt;
&lt;br /&gt;
#ifndef _PRINTX_H_&lt;br /&gt;
#define _PRINTX_H_&lt;br /&gt;
#include &amp;lt;iomanip&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// helper function which appends an array of asterisks to ostream&lt;br /&gt;
void append_asterisks(std::ios_base&amp;amp; os, int nCount);&lt;br /&gt;
&lt;br /&gt;
// custom manipulator, based on std::_Smanip macro&lt;br /&gt;
std::_Smanip&lt;int&gt; __cdecl insert_asterisks(int nCount);&lt;/int&gt;&lt;br /&gt;
#endif //_PRINTX_H_&lt;/div&gt;
&lt;br /&gt;
printx.cpp:
&lt;br /&gt;
&lt;div class="my_code"&gt;
&lt;br /&gt;
#include "printx.h"&lt;br /&gt;
&lt;br /&gt;
void append_asterisks(std::ios_base&amp;amp; os, int nCount)&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; &amp;nbsp;std::ostream* pos = dynamic_cast &amp;lt;std::ostream*&amp;gt;(&amp;amp;os);&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp;if(pos)&lt;br /&gt;
&amp;nbsp; &amp;nbsp;{&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; for(int i = 0; i &amp;lt; nCount; i++)&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; (*pos) &amp;lt;&amp;lt; '*';&lt;br /&gt;
&amp;nbsp; &amp;nbsp;};&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
std::_Smanip&amp;lt;int&amp;gt; __cdecl insert_asterisks(int no)&lt;br /&gt;
{ &lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;return (std::_Smanip&amp;lt;int&amp;gt;(&amp;amp;append_asterisks, no));&lt;br /&gt;
}
&lt;/div&gt;
&lt;br /&gt;
We are using this function in our main:
&lt;br /&gt;
main.cpp:
&lt;br /&gt;
&lt;div class="my_code"&gt;
&lt;br /&gt;
#include &amp;lt;iostream&amp;gt;&lt;br /&gt;
#include "printx.h"&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;std::cout &amp;lt;&amp;lt; insert_asterisks(10) &amp;nbsp;&amp;lt;&amp;lt; "Hello, world!" &amp;lt;&amp;lt; insert_asterisks(10) &amp;lt;&amp;lt; std::endl;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;return 0;&lt;br /&gt;
}&lt;/div&gt;
&lt;br /&gt;
New makefile uses following compiler options:&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&lt;b&gt;/EHsc&lt;/b&gt; - to suppress previous compiler warning related to exceptions handling&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&lt;b&gt;/Fe&lt;/b&gt; - to define binary output destination directory&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&lt;b&gt;/I&lt;/b&gt; - to provide path to header file(s)&lt;br /&gt;
&lt;br /&gt;
It contains pseudo-targets which operate on directory structure ("create_dirs", "clean") and one that groups all actions into a single command ("all").
&lt;br /&gt;
&lt;br /&gt;
makefile:
&lt;br /&gt;
&lt;div class="my_code"&gt;
&lt;br /&gt;
#define macros&lt;br /&gt;
EXECUTABLE_NAME = helloworld.exe&lt;br /&gt;
DIR_SRC = ..\src&lt;br /&gt;
DIR_INCLUDE = ..\include&lt;br /&gt;
DIR_BIN = ..\bin&lt;br /&gt;
DIR_BIN_X86 = $(DIR_BIN)\x86&lt;br /&gt;
DIR_INTERMEDIATE = ..\intermediate&lt;br /&gt;
DIR_INTERMEDIATE_X86 = $(DIR_INTERMEDIATE)\x86&lt;br /&gt;
&lt;br /&gt;
SRC_FILES= \&lt;br /&gt;
&amp;nbsp; $(DIR_SRC)\main.cpp \&lt;br /&gt;
&amp;nbsp; $(DIR_SRC)\printx.cpp&lt;br /&gt;
&lt;br /&gt;
# description block&lt;br /&gt;
$(EXECUTABLE_NAME) : $(SRC_FILES)&lt;br /&gt;
&amp;nbsp; cl /EHsc /Fe$(DIR_BIN_X86)\$(EXECUTABLE_NAME) /I$(DIR_INCLUDE) $(SRC_FILES)&lt;br /&gt;
&amp;nbsp; copy *.obj $(DIR_INTERMEDIATE_X86)&lt;br /&gt;
&amp;nbsp; del *.obj&lt;br /&gt;
&lt;br /&gt;
# build application&lt;br /&gt;
helloworld: $(EXECUTABLE_NAME)&lt;br /&gt;
&lt;br /&gt;
# create output directories&lt;br /&gt;
create_dirs:&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;@if not exist $(DIR_BIN_X86) mkdir $(DIR_BIN_X86)&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;@if not exist $(DIR_INTERMEDIATE_X86) mkdir $(DIR_INTERMEDIATE_X86)&lt;br /&gt;
&lt;br /&gt;
# delete output directories&lt;br /&gt;
clean:&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;@if exist $(DIR_BIN) rmdir /S /Q $(DIR_BIN)&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;@if exist $(DIR_INTERMEDIATE) rmdir /S /Q $(DIR_INTERMEDIATE)&lt;br /&gt;
&lt;br /&gt;
# create directories and build application&lt;br /&gt;
all: clean create_dirs helloworld&lt;/div&gt;
&lt;br /&gt;
Here's the order of commands in the command prompt window:
&lt;br /&gt;
&lt;div class="cmd_line"&gt;
&lt;br /&gt;
C:\DEVELOPMENT\RESEARCH\C++\HelloWorld\build&amp;gt;nmake all&lt;br /&gt;
&lt;br /&gt;
Microsoft (R) Program Maintenance Utility Version 10.00.30319.01&lt;br /&gt;
Copyright (C) Microsoft Corporation. &amp;nbsp;All rights reserved.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cl /EHsc /Fe..\bin\x86\helloworld.exe /I..\include ..\src\main.cpp &amp;nbsp;..\s&lt;br /&gt;
rc\printx.cpp&lt;br /&gt;
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.30319.01 for 80x86&lt;br /&gt;
Copyright (C) Microsoft Corporation. &amp;nbsp;All rights reserved.&lt;br /&gt;
&lt;br /&gt;
main.cpp&lt;br /&gt;
printx.cpp&lt;br /&gt;
Generating Code...&lt;br /&gt;
Microsoft (R) Incremental Linker Version 10.00.30319.01&lt;br /&gt;
Copyright (C) Microsoft Corporation. &amp;nbsp;All rights reserved.&lt;br /&gt;
&lt;br /&gt;
/out:..\bin\x86\helloworld.exe&lt;br /&gt;
main.obj&lt;br /&gt;
printx.obj&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; copy *.obj ..\intermediate\x86&lt;br /&gt;
main.obj&lt;br /&gt;
printx.obj&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 2 file(s) copied.&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; del *.obj&lt;br /&gt;
&lt;br /&gt;
C:\DEVELOPMENT\RESEARCH\C++\HelloWorld\build&amp;gt;cd "..\bin\x86"&lt;br /&gt;
&lt;br /&gt;
C:\DEVELOPMENT\RESEARCH\C++\HelloWorld\bin\x86&amp;gt;helloworld.exe&lt;br /&gt;
**********Hello, world!**********&lt;br /&gt;
&lt;br /&gt;
C:\DEVELOPMENT\RESEARCH\C++\HelloWorld\bin\x86&amp;gt;&lt;/div&gt;
&lt;br /&gt;
We can separate compiling from linking in two steps - compiling source files into object files and linking object files into executable.
&lt;br /&gt;
&lt;br /&gt;
makefile:
&lt;br /&gt;
&lt;div class="my_code"&gt;
&lt;br /&gt;
#define macros&lt;br /&gt;
EXECUTABLE_NAME = helloworld.exe&lt;br /&gt;
DIR_SRC = ..\src&lt;br /&gt;
DIR_INCLUDE = ..\include&lt;br /&gt;
DIR_BIN = ..\bin&lt;br /&gt;
DIR_BIN_X86 = $(DIR_BIN)\x86&lt;br /&gt;
DIR_INTERMEDIATE = ..\intermediate&lt;br /&gt;
DIR_INTERMEDIATE_X86 = $(DIR_INTERMEDIATE)\x86&lt;br /&gt;
&lt;br /&gt;
OBJ_FILES = \&lt;br /&gt;
&amp;nbsp; $(DIR_INTERMEDIATE_X86)\main.obj \&lt;br /&gt;
&amp;nbsp; $(DIR_INTERMEDIATE_X86)\printx.obj&lt;br /&gt;
&lt;br /&gt;
$(DIR_INTERMEDIATE_X86)\main.obj: $(DIR_SRC)\main.cpp&lt;br /&gt;
&amp;nbsp; &lt;b&gt;&lt;span class="Apple-style-span" style="color: red;"&gt;cl&lt;/span&gt;&lt;/b&gt; /c /EHsc /Fe$(DIR_INTERMEDIATE_X86)\main.obj /I$(DIR_INCLUDE) $(DIR_SRC)\main.cpp&lt;br /&gt;
&amp;nbsp; copy main.obj $(DIR_INTERMEDIATE_X86)&lt;br /&gt;
&amp;nbsp; del main.obj&lt;br /&gt;
&lt;br /&gt;
$(DIR_INTERMEDIATE_X86)\printx.obj: $(DIR_SRC)\printx.cpp&lt;br /&gt;
&amp;nbsp; &lt;span class="Apple-style-span" style="color: red;"&gt;&lt;b&gt;cl &lt;/b&gt;&lt;/span&gt;/c /EHsc /Fe$(DIR_INTERMEDIATE_X86)\printx.obj /I$(DIR_INCLUDE) $(DIR_SRC)\printx.cpp&lt;br /&gt;
&amp;nbsp; copy printx.obj $(DIR_INTERMEDIATE_X86)&lt;br /&gt;
&amp;nbsp; del printx.obj&lt;br /&gt;
&lt;br /&gt;
$(EXECUTABLE_NAME) : $(OBJ_FILES)&lt;br /&gt;
&amp;nbsp; &amp;nbsp;&lt;span class="Apple-style-span" style="color: red;"&gt;&lt;b&gt;link &lt;/b&gt;&lt;/span&gt;/out:$(DIR_BIN_X86)\$(EXECUTABLE_NAME) $(OBJ_FILES)&lt;br /&gt;
&lt;br /&gt;
# build application&lt;br /&gt;
helloworld: $(EXECUTABLE_NAME)&lt;br /&gt;
&lt;br /&gt;
# create output directories&lt;br /&gt;
create_dirs:&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;@if not exist $(DIR_BIN_X86) mkdir $(DIR_BIN_X86)&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;@if not exist $(DIR_INTERMEDIATE_X86) mkdir $(DIR_INTERMEDIATE_X86)&lt;br /&gt;
&lt;br /&gt;
# delete output directories&lt;br /&gt;
clean:&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;@if exist $(DIR_BIN) rmdir /S /Q $(DIR_BIN)&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;@if exist $(DIR_INTERMEDIATE) rmdir /S /Q $(DIR_INTERMEDIATE)&lt;br /&gt;
&lt;br /&gt;
# create directories and build application&lt;br /&gt;
all: clean create_dirs helloworld&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
We can avoid repeating description blocks for each OBJ file by using inference rules. They are generic description blocks that define rules of how files with one extension are converted into files with the same name but different extensions. These rules are applied when resolving dependants. In the following makefile, EXE depends on OBJ files and inference rule defines how are OBJ files generated from CPP files:&lt;br /&gt;
&lt;br /&gt;
makefile:
&lt;br /&gt;
&lt;div class="my_code"&gt;
&lt;br /&gt;
#define macros&lt;br /&gt;
EXECUTABLE_NAME = helloworld.exe&lt;br /&gt;
DIR_SRC = ..\src&lt;br /&gt;
DIR_INCLUDE = ..\include&lt;br /&gt;
DIR_BIN = ..\bin&lt;br /&gt;
DIR_BIN_X86 = $(DIR_BIN)\x86&lt;br /&gt;
DIR_INTERMEDIATE = ..\intermediate&lt;br /&gt;
DIR_INTERMEDIATE_X86 = $(DIR_INTERMEDIATE)\x86&lt;br /&gt;
&lt;br /&gt;
SRC_FILES= \&lt;br /&gt;
&amp;nbsp; $(DIR_SRC)\main.cpp \&lt;br /&gt;
&amp;nbsp; $(DIR_SRC)\printx.cpp&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="color: red;"&gt;{$(DIR_SRC)}.cpp{$(DIR_INTERMEDIATE_X86)}.obj ::&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="color: red;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; @echo Compiling...&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="color: red;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;cl /c /EHsc /Fo$(DIR_INTERMEDIATE_X86)\ /I$(DIR_INCLUDE) $&amp;lt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
$(EXECUTABLE_NAME) : $(DIR_INTERMEDIATE_X86)\*.obj&lt;br /&gt;
&amp;nbsp; &amp;nbsp;@echo Linking $(EXECUTABLE_NAME)...&lt;br /&gt;
&amp;nbsp; &amp;nbsp;link /out:$(DIR_BIN_X86)\$(EXECUTABLE_NAME) $(DIR_INTERMEDIATE_X86)\*.obj&lt;br /&gt;
&lt;br /&gt;
# build application&lt;br /&gt;
helloworld: $(EXECUTABLE_NAME)&lt;br /&gt;
&lt;br /&gt;
# create output directories&lt;br /&gt;
create_dirs:&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;@if not exist $(DIR_BIN_X86) mkdir $(DIR_BIN_X86)&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;@if not exist $(DIR_INTERMEDIATE_X86) mkdir $(DIR_INTERMEDIATE_X86)&lt;br /&gt;
&lt;br /&gt;
# delete output directories&lt;br /&gt;
clean:&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;@if exist $(DIR_BIN) rmdir /S /Q $(DIR_BIN)&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;	&lt;/span&gt;@if exist $(DIR_INTERMEDIATE) rmdir /S /Q $(DIR_INTERMEDIATE)&lt;br /&gt;
&lt;br /&gt;
# create directories and build application&lt;br /&gt;
all: clean create_dirs helloworld&lt;/div&gt;
&lt;br /&gt;
Here is the order of commands in the command prompt window:
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="cmd_line"&gt;
&lt;br /&gt;
C:\DEVELOPMENT\RESEARCH\C++\HelloWorld\build&amp;gt;nmake all&lt;br /&gt;
&lt;br /&gt;
Microsoft (R) Program Maintenance Utility Version 10.00.30319.01&lt;br /&gt;
Copyright (C) Microsoft Corporation. &amp;nbsp;All rights reserved.&lt;br /&gt;
&lt;br /&gt;
Compiling...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; cl /c /EHsc /Fo..\intermediate\x86\ /I..\include ..\src\*.cpp&lt;br /&gt;
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.30319.01 for 80x86&lt;br /&gt;
Copyright (C) Microsoft Corporation. &amp;nbsp;All rights reserved.&lt;br /&gt;
&lt;br /&gt;
main.cpp&lt;br /&gt;
printx.cpp&lt;br /&gt;
Generating Code...&lt;br /&gt;
Linking helloworld.exe...&lt;br /&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; link /out:..\bin\x86\helloworld.exe ..\intermediate\x86\*.obj&lt;br /&gt;
Microsoft (R) Incremental Linker Version 10.00.30319.01&lt;br /&gt;
Copyright (C) Microsoft Corporation. &amp;nbsp;All rights reserved.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
C:\DEVELOPMENT\RESEARCH\C++\HelloWorld\build&amp;gt;cd "..\bin\x86"&lt;br /&gt;
&lt;br /&gt;
C:\DEVELOPMENT\RESEARCH\C++\HelloWorld\bin\x86&amp;gt;helloworld.exe&lt;br /&gt;
**********Hello, world!**********&lt;br /&gt;
&lt;br /&gt;
C:\DEVELOPMENT\RESEARCH\C++\HelloWorld\bin\x86&amp;gt;&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
Links and references:
&lt;br /&gt;
&lt;a href="Make (software)"&gt;Make (software) (Wikipedia)&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/dd9y37ha.aspx"&gt;NMAKE Reference (MSDN)&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/91621w01.aspx"&gt;C/C++ Building Reference (MSDN)&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://support.microsoft.com/kb/60340"&gt;Example Demonstrates Using Paths in NMAKE (MSDN)&lt;/a&gt;&lt;br /&gt;
&lt;a href="https://users.cs.jmu.edu/bernstdh/web/common/help/msc_nmake.php"&gt;MS C/C++: The nmake Command&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.opussoftware.com/tutorial/TutMakefile.htm"&gt;The Makefile&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://c2.com/cgi/wiki?UsingNmake"&gt;Using Nmake&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.tidytutorials.com/2009/08/nmake-makefile-tutorial-and-example.html"&gt;Nmake Makefile Tutorial and Example&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.opensource.apple.com/source/libxslt/libxslt-7/libxslt/win32/Makefile.msvc"&gt;Makefile.msvc (makefile example)&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.dgp.toronto.edu/~ah/csc418/fall_2001/tut/msvcpp.html"&gt;Building a simple OpenGL application&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://courses.cs.vt.edu/~cs1704/fall03/Notes/A10.NMAKE.pdf"&gt;NMAKE (course; pdf)&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://web.sau.edu/lilliskevinm/csci240/masmdocs/envtools/26LMAETC16.pdf"&gt;Managing Projects with NMAKE&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.dmi.unict.it/~tramonta/lessons/so/makedoc.pdf"&gt;The make utility&lt;/a&gt;&lt;br /&gt;
&lt;/div&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4912226416400969049-3001767267149329863?l=bojan-komazec.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/tdrAxSB26uF41aQxb5XYSF2Vowc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/tdrAxSB26uF41aQxb5XYSF2Vowc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/tdrAxSB26uF41aQxb5XYSF2Vowc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/tdrAxSB26uF41aQxb5XYSF2Vowc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/MyPublicNotepad/~4/W96sjIm77Fo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://bojan-komazec.blogspot.com/feeds/3001767267149329863/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4912226416400969049&amp;postID=3001767267149329863" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/3001767267149329863?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/3001767267149329863?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyPublicNotepad/~3/W96sjIm77Fo/how-to-use-nmake-and-makefile.html" title="How to use nmake and makefile" /><author><name>Bojan Komazec</name><uri>https://profiles.google.com/117174187628268281803</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total><feedburner:origLink>http://bojan-komazec.blogspot.com/2011/10/how-to-use-nmake-and-makefile.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkINQXkyeyp7ImA9WhdUGUU.&quot;"><id>tag:blogger.com,1999:blog-4912226416400969049.post-3854517195056941814</id><published>2011-10-03T18:35:00.000+01:00</published><updated>2011-10-07T10:43:10.793+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-07T10:43:10.793+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="environment variables" /><category scheme="http://www.blogger.com/atom/ns#" term="Batch file" /><category scheme="http://www.blogger.com/atom/ns#" term="Windows" /><category scheme="http://www.blogger.com/atom/ns#" term="Computer architecture" /><category scheme="http://www.blogger.com/atom/ns#" term="Visual Studio" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><category scheme="http://www.blogger.com/atom/ns#" term="NMAKE" /><title>NMAKE and its environment</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;&lt;b&gt;nmake&lt;/b&gt; is a Microsoft's command-line tool for building C/C++ applications.  nmake comes with Visual Studio and Windows Driver Development Kit (DDK) and it comes in two versions: one for building 32-bit and another for building 64-bit binaries. Here is the list of its locations, depending on which Microsoft product is installed on your machine: &lt;br /&gt;
&lt;br /&gt;
Visual Studio 2010: &lt;br /&gt;
&lt;div class="file_hierarchy"&gt;C:\Program Files\Microsoft Visual Studio 10.0\VC\bin\nmake.exe&lt;br /&gt;
(32-bit binary; depends on 32-bit advapi32.dll, kernel32.dll and msvcr100.dll)&lt;br /&gt;
&lt;br /&gt;
C:\Program Files\Microsoft Visual Studio 10.0\VC\bin\amd64\nmake.exe&lt;br /&gt;
(64-bit binary; depends on 64-bit advapi32.dll, kernel32.dll and msvcr100.dll) &lt;/div&gt;&lt;br /&gt;
Visual Studio 2008: &lt;br /&gt;
&lt;div class="file_hierarchy"&gt;C:\Program Files\Microsoft Visual Studio 9.0\VC\bin\nmake.exe&lt;br /&gt;
(32-bit binary; depends on 32-bit advapi32.dll, kernel32.dll and msvcr90.dll)&lt;br /&gt;
&lt;br /&gt;
C:\Program Files\Microsoft Visual Studio 9.0\VC\bin\amd64\nmake.exe&lt;br /&gt;
(64-bit binary; depends on 64-bit advapi32.dll, kernel32.dll and msvcr90.dll) &lt;/div&gt;&lt;br /&gt;
Windows DDK (I have some pretty old installed on my machine): &lt;br /&gt;
&lt;div class="file_hierarchy"&gt;C:\WinDDK\6001.18001\bin\x86\nmake.exe&lt;br /&gt;
(32-bit binary; depends on 32-bit advapi32.dll, kernel32.dll and msvcr80.dll)&lt;br /&gt;
&lt;br /&gt;
C:\WinDDK\6001.18001\bin\ia64\nmake.exe&lt;br /&gt;
(64-bit binary; depends on 64-bit advapi32.dll, kernel32.dll and msvcr80.dll) &lt;/div&gt;&lt;br /&gt;
Binaries from amd64/ia64 directories are 64-bit and cannot be run on 32-bit machines.  &lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;msvcrXX.dll&lt;/b&gt; is &lt;b&gt;Microsoft Visual C Runtime library&lt;/b&gt;. XX is its version, specific for each version of Visual Studio: 80 for VS2005, 90 for VS2008 and 100 for VS2010. Binary linked against some msvcr library requires existence of that library on the machine it runs on. If it does not exist, it can be installed with &lt;b&gt;Microsoft Visual C++ VS20XX Redistributable Package&lt;/b&gt; (x86 or x64). &lt;br /&gt;
&lt;br /&gt;
If you want to run some particular nmake on your machine, make sure its path is listed in &lt;b&gt;Paths &lt;/b&gt;environment variable. If there are more versions of nmake present on your machine, put path to desired version before paths to the other versions. E.g. put path "C:\Program Files\Microsoft Visual Studio 10.0\VC\bin" before "C:\Program Files\Microsoft Visual Studio 9.0\VC\bin" in Paths if you want to run VS2010 nmake. You can always check which nmake will be called  from some arbitrary location if executing (from a command line): &lt;br /&gt;
&lt;br /&gt;
&lt;div class="cmd_line"&gt;where nmake  &lt;/div&gt;&lt;br /&gt;
If nmake resides in multiple directories, all those directories will be listed but only instance from the first listed will be called, &lt;br /&gt;
nmake reads instructions from a file called &lt;b&gt;makefile&lt;/b&gt; (full name of this file usually does not contain a dot and extension). Instructions of how to build a specific binary (or binaries) are grouped into named &lt;b&gt;targets&lt;/b&gt;. Those instructions contain compiler and linker calls, provided with source files, paths to headers, dependencies, object file names and compiler and linker options. Tags for groups of targets or sets of instructions that don't make binaries (like creating or deleting files or directories) are &lt;b&gt;pseudo-targets&lt;/b&gt;.  &lt;br /&gt;
&lt;br /&gt;
You need to provide target or pseudo-target name when calling nmake. You can provide path to makefile; without it nmake looks for it in the current directory.  &lt;br /&gt;
&lt;br /&gt;
makefile contains instruction to call Microsoft compiler, &lt;b&gt;cl.exe&lt;/b&gt; and linker, &lt;b&gt;link.exe&lt;/b&gt;. Just like nmake, they come with Visual Studio and Windows DDK. &lt;br /&gt;
&lt;br /&gt;
Visual Studio 2010: &lt;br /&gt;
&lt;div class="file_hierarchy"&gt;c:\Program Files\Microsoft Visual Studio 10.0\VC\bin\amd64\cl.exe&lt;br /&gt;
c:\Program Files\Microsoft Visual Studio 10.0\VC\bin\amd64\link.exe&lt;br /&gt;
(64-bit compiler and linker for AMD64 architecture)&lt;br /&gt;
&lt;br /&gt;
c:\Program Files\Microsoft Visual Studio 10.0\VC\bin\cl.exe&lt;br /&gt;
c:\Program Files\Microsoft Visual Studio 10.0\VC\bin\link.exe&lt;br /&gt;
(32-bit compiler and linker for building 32-bit applications)&lt;br /&gt;
&lt;br /&gt;
c:\Program Files\Microsoft Visual Studio 10.0\VC\bin\x86_amd64\cl.exe&lt;br /&gt;
(depends on advapi32.dll, kernel32.dll, msvcr100.dll, version.dll, psapi.dll and shell32.dll from C:\Windows\System32 and mspdb100.dll from c:\program files\microsoft visual studio 10.0\common7\ide)&lt;br /&gt;
&lt;br /&gt;
c:\Program Files\Microsoft Visual Studio 10.0\VC\bin\x86_amd64\link.exe&lt;br /&gt;
(depends on advapi32.dll, kernel32.dll, msvcr100.dll, psapi.dll and user32.dll from C:\Windows\System32 and mspdb100.dll from c:\program files\microsoft visual studio 10.0\common7\ide) (32-bit cross-compiler and linker for building 64-bit applications for AMD64 architectures)&lt;br /&gt;
&lt;br /&gt;
c:\Program Files\Microsoft Visual Studio 10.0\VC\bin\x86_ia64\cl.exe&lt;br /&gt;
c:\Program Files\Microsoft Visual Studio 10.0\VC\bin\x86_ia64\link.exe&lt;br /&gt;
(32-bit cross-compiler and linker for building 64-bit applications for Itanium architectures)&lt;/div&gt;&lt;br /&gt;
Visual Studio 2008: &lt;br /&gt;
&lt;div class="file_hierarchy"&gt;c:\Program Files\Microsoft Visual Studio 9.0\VC\bin\amd64\cl.exe&lt;br /&gt;
c:\Program Files\Microsoft Visual Studio 9.0\VC\bin\amd64\link.exe&lt;br /&gt;
&lt;br /&gt;
c:\Program Files\Microsoft Visual Studio 9.0\VC\bin\cl.exe&lt;br /&gt;
c:\Program Files\Microsoft Visual Studio 9.0\VC\bin\link.exe&lt;br /&gt;
&lt;br /&gt;
c:\Program Files\Microsoft Visual Studio 9.0\VC\bin\x86_amd64\cl.exe&lt;br /&gt;
c:\Program Files\Microsoft Visual Studio 9.0\VC\bin\x86_amd64\link.exe&lt;br /&gt;
&lt;br /&gt;
c:\Program Files\Microsoft Visual Studio 9.0\VC\ce\bin\x86_arm\cl.exe&lt;br /&gt;
c:\Program Files\Microsoft Visual Studio 9.0\VC\ce\bin\x86_arm\link.exe&lt;br /&gt;
&lt;br /&gt;
c:\Program Files\Microsoft Visual Studio 9.0\VC\ce\bin\x86_mips\cl.exe&lt;br /&gt;
c:\Program Files\Microsoft Visual Studio 9.0\VC\ce\bin\x86_mips\link.exe&lt;br /&gt;
&lt;br /&gt;
c:\Program Files\Microsoft Visual Studio 9.0\VC\ce\bin\x86_sh\cl.exe&lt;br /&gt;
c:\Program Files\Microsoft Visual Studio 9.0\VC\ce\bin\x86_sh\link.exe&lt;/div&gt;&lt;br /&gt;
Windows DDK: &lt;br /&gt;
&lt;div class="file_hierarchy"&gt;c:\WinDDK\6001.18001\bin\ia64\ia64\cl.exe&lt;br /&gt;
c:\WinDDK\6001.18001\bin\ia64\ia64\link.exe&lt;br /&gt;
c:\WinDDK\6001.18001\bin\x86\amd64\cl.exe&lt;br /&gt;
c:\WinDDK\6001.18001\bin\x86\amd64\link.exe&lt;br /&gt;
c:\WinDDK\6001.18001\bin\x86\ia64\cl.exe&lt;br /&gt;
c:\WinDDK\6001.18001\bin\x86\ia64\link.exe&lt;br /&gt;
c:\WinDDK\6001.18001\bin\x86\x86\cl.exe&lt;br /&gt;
c:\WinDDK\6001.18001\bin\x86\x86\link.exe&lt;/div&gt;&lt;br /&gt;
Again, which compiler and linker will be called depends on paths listed in Path environment variable. Paths used can be checked by calling (from a command line): &lt;br /&gt;
&lt;br /&gt;
&lt;div class="cmd_line"&gt;where cl.exe&lt;br /&gt;
where link.exe &lt;/div&gt;&lt;br /&gt;
For example, if we want to build some 64-bit application for AMD architecture (which is usually named x64 and is more common than Itanium one) and we we want to build it on 32-bit machine, using VS2010, we need to use cross-compiler and so will add following paths to Path environment variable: &lt;br /&gt;
&lt;div class="file_hierarchy"&gt;C:\Windows\System32; (path to dlls used by cl.exe and link.exe)&lt;br /&gt;
c:\program files\microsoft visual studio 10.0\common7\ide; (path to dlls used by cl.exe and link.exe)&lt;br /&gt;
C:\Program Files\Microsoft Visual Studio 10.0\VC\bin\x86_amd64; (path to cl.exe and link.exe)&lt;br /&gt;
C:\Program Files\Microsoft Visual Studio 10.0\VC\bin; (path to nmake.exe) &lt;/div&gt;&lt;br /&gt;
If you try to run 64-bit compiler on 32-bit machine, you'll get message: &lt;br /&gt;
&lt;div class="cmd_line"&gt;c:\Program Files\Microsoft Visual Studio 10.0\VC\bin\amd64&amp;gt;cl.exe /?&lt;br /&gt;
This version of c:\Program Files\Microsoft Visual Studio 10.0\VC\bin\amd64\cl.ex&lt;br /&gt;
e is not compatible with the version of Windows you're running. Check your compu&lt;br /&gt;
ter's system information to see whether you need a x86 (32-bit) or x64 (64-bit)&lt;br /&gt;
version of the program, and then contact the software publisher. &lt;/div&gt;&lt;br /&gt;
You can run 32-bit compiler or 32-bit cross-compiler on 32-bit machine only: &lt;br /&gt;
&lt;div class="cmd_line"&gt;c:\Program Files\Microsoft Visual Studio 10.0\VC\bin\x86_amd64&amp;gt;cl.exe /?&lt;br /&gt;
Microsoft (R) C/C++ Optimizing Compiler Version 16.00.30319.01 for x64&lt;br /&gt;
Copyright (C) Microsoft Corporation.  All rights reserved. &lt;/div&gt;&lt;br /&gt;
This is not enough for nmake build to be successful. Compiler reads paths to Visual C++ and Windows SDK (Windows Framework) headers from &lt;b&gt;INCLUDE&lt;/b&gt; environment variable. These headers are coming with each version of Visual Studio and we need to make sure cl.exe will be using correct ones. For example, if we want to use VS2010, we will set INCLUDE as:  &lt;br /&gt;
&lt;div class="file_hierarchy"&gt;c:\Program Files\Microsoft Visual Studio 10.0\VC\include; (Visual C++ headers - part of Microsoft's implementation of C++ standard)&lt;br /&gt;
c:\Program Files\Microsoft Visual Studio 10.0\VC\atlmfc\include; (ATL/MFC headers - add this path only for this type of applications)&lt;br /&gt;
c:\Program Files\Microsoft SDKs\Windows\v7.0A\include; (Windows SDK headers) &lt;/div&gt;&lt;br /&gt;
Furthermore, linker reads paths to Visual C++ and Windows Framework libraries from &lt;b&gt;LIB &lt;/b&gt;environment variable. These libraries are specific for each version of Visual Studio and target architecture. If using VS2010 and building binary for AMD64 architecture, we would set LIB as: &lt;br /&gt;
&lt;div class="file_hierarchy"&gt;c:\Program Files\Microsoft Visual Studio 10.0\VC\lib\amd64; (Visual C++ libraries)&lt;br /&gt;
c:\Program Files\Microsoft Visual Studio 10.0\VC\atlmfc\lib\amd64; (ATL/MFC libraries- add this path only for this type of applications)&lt;br /&gt;
c:\Program Files\Microsoft SDKs\Windows\v7.0A\lib\x64; (Windows SDK libraries) &lt;/div&gt;&lt;br /&gt;
Of course, if your application depends on some other framework or package, INCLUDE needs to contain path to its headers and LIB path to its libraries. &lt;br /&gt;
&lt;br /&gt;
I wrote one short batch file for setting Visual Studio environment (environmental variables) for x86 or x64 builds: &lt;br /&gt;
&lt;a name="setenv.bat"&gt;setenv.bat&lt;/a&gt; (caret character is used to break long lines): &lt;br /&gt;
&lt;div class="my_code"&gt;@rem B.Komazec Setting environment for using Microsoft Visual Studio 2010 x86/x64 tools.&lt;br /&gt;
@echo off&lt;br /&gt;
&lt;br /&gt;
@if "%1"=="x86" goto set_x86&lt;br /&gt;
@if "%1"=="x64" goto set_x64&lt;br /&gt;
@if "%1"=="" goto error&lt;br /&gt;
&lt;br /&gt;
:set_x86&lt;br /&gt;
@echo Setting environment for using Microsoft Visual Studio 2010 x86 tools.&lt;br /&gt;
&lt;br /&gt;
set INCLUDE=^&lt;br /&gt;
c:\Program Files\Microsoft Visual Studio 10.0\VC\include;^&lt;br /&gt;
c:\Program Files\Microsoft SDKs\Windows\v7.0A\include;&lt;br /&gt;
&lt;br /&gt;
set LIB=^&lt;br /&gt;
c:\Program Files\Microsoft Visual Studio 10.0\VC\lib;^&lt;br /&gt;
c:\Program Files\Microsoft SDKs\Windows\v7.0A\lib;&lt;br /&gt;
&lt;br /&gt;
set PATH=^&lt;br /&gt;
%SystemRoot%\system32;^&lt;br /&gt;
c:\Program Files\Microsoft Visual Studio 10.0\VC\bin;^&lt;br /&gt;
c:\program files\microsoft visual studio 10.0\common7\ide;&lt;br /&gt;
&lt;br /&gt;
goto test_bin_locations&lt;br /&gt;
&lt;br /&gt;
:set_x64&lt;br /&gt;
@echo Setting environment for using Microsoft Visual Studio 2010 x64 tools.&lt;br /&gt;
&lt;br /&gt;
set INCLUDE=^&lt;br /&gt;
c:\Program Files\Microsoft Visual Studio 10.0\VC\include;^&lt;br /&gt;
c:\Program Files\Microsoft SDKs\Windows\v7.0A\include;&lt;br /&gt;
&lt;br /&gt;
set LIB=^&lt;br /&gt;
c:\Program Files\Microsoft Visual Studio 10.0\VC\lib\amd64;^&lt;br /&gt;
c:\Program Files\Microsoft SDKs\Windows\v7.0A\lib\x64;&lt;br /&gt;
&lt;br /&gt;
set PATH=^&lt;br /&gt;
%SystemRoot%\system32;^&lt;br /&gt;
C:\Program Files\Microsoft Visual Studio 10.0\VC\bin\x86_amd64;^&lt;br /&gt;
C:\Program Files\Microsoft Visual Studio 10.0\VC\bin;^&lt;br /&gt;
C:\Program Files\Microsoft Visual Studio 10.0\Common7\ide;&lt;br /&gt;
&lt;br /&gt;
goto test_bin_locations&lt;br /&gt;
&lt;br /&gt;
:test_bin_locations&lt;br /&gt;
@echo on&lt;br /&gt;
where nmake&lt;br /&gt;
where cl.exe&lt;br /&gt;
where link.exe&lt;br /&gt;
@echo off&lt;br /&gt;
goto:eof&lt;br /&gt;
&lt;br /&gt;
:error&lt;br /&gt;
@echo Usage: setenv.bat [x86^|x64]&lt;br /&gt;
&lt;br /&gt;
goto:eof&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
For example, to set environment for building x64 (AMD64) application with VS2010, call this script providing "x64" as an argument: &lt;br /&gt;
&lt;br /&gt;
&lt;div class="cmd_line"&gt;setenv x64 &lt;/div&gt;&lt;br /&gt;
Note that changes made with SET will remain only for the duration of the current CMD session. To check the value of some environment variable in command prompt window use ECHO command followed by environment variable surrounded with percent signs: &lt;br /&gt;
&lt;br /&gt;
&lt;div class="cmd_line"&gt;echo %Path% &lt;/div&gt;&lt;br /&gt;
You can also use batch files that come with Visual Studio: &lt;br /&gt;
Visual Studio 2010: &lt;br /&gt;
&lt;div class="file_hierarchy"&gt;C:\Program Files\Microsoft Visual Studio 10.0\VC\bin\vcvars32.bat&lt;br /&gt;
C:\Program Files\Microsoft Visual Studio 10.0\VC\bin\x86_amd64\vcvarsx86_amd64.bat&lt;br /&gt;
C:\Program Files\Microsoft Visual Studio 10.0\VC\bin\x86_ia64\vcvarsx86_ia64.bat&lt;br /&gt;
C:\Program Files\Microsoft Visual Studio 10.0\VC\vcvarsall.bat &lt;/div&gt;&lt;br /&gt;
Visual Studio 2008: &lt;br /&gt;
&lt;div class="file_hierarchy"&gt;C:\Program Files\Microsoft Visual Studio 9.0\VC\bin\amd64\vcvarsamd64.bat&lt;br /&gt;
C:\Program Files\Microsoft Visual Studio 9.0\VC\bin\vcvars32.bat&lt;br /&gt;
C:\Program Files\Microsoft Visual Studio 9.0\VC\bin\x86_amd64\vcvarsx86_amd64.bat&lt;br /&gt;
C:\Program Files\Microsoft Visual Studio 9.0\VC\vcvarsall.bat &lt;/div&gt;&lt;br /&gt;
Links and references: &lt;br /&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/dd9y37ha.aspx"&gt;NMAKE Reference (MSDN)&lt;/a&gt; &lt;br /&gt;
&lt;a href="http://www.cs.duke.edu/courses/cps108/doc/makefileinfo/html/Makefiles.html"&gt;An introduction to Makefiles&lt;/a&gt; &lt;br /&gt;
&lt;a href="http://www.tidytutorials.com/2009/08/nmake-makefile-tutorial-and-example.html"&gt;Nmake Makefile Tutorial and Example&lt;/a&gt; &lt;br /&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/kezkeayy.aspx"&gt;CL Environment Variables&lt;/a&gt; &lt;br /&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/6y6t9esh.aspx"&gt;LINK Environment Variables&lt;/a&gt; &lt;br /&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/f2ccy3wt.aspx"&gt;Setting the Path and Environment Variables for Command-Line Builds&lt;/a&gt; &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4912226416400969049-3854517195056941814?l=bojan-komazec.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ZrrWkQywWLpDXs80LHyAnFp1fQs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ZrrWkQywWLpDXs80LHyAnFp1fQs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ZrrWkQywWLpDXs80LHyAnFp1fQs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ZrrWkQywWLpDXs80LHyAnFp1fQs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/MyPublicNotepad/~4/0sQIZe67l88" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://bojan-komazec.blogspot.com/feeds/3854517195056941814/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4912226416400969049&amp;postID=3854517195056941814" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/3854517195056941814?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/3854517195056941814?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyPublicNotepad/~3/0sQIZe67l88/nmake-and-its-environment.html" title="NMAKE and its environment" /><author><name>Bojan Komazec</name><uri>https://profiles.google.com/117174187628268281803</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://bojan-komazec.blogspot.com/2011/10/nmake-and-its-environment.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEcBQHw9cSp7ImA9WhdVFkw.&quot;"><id>tag:blogger.com,1999:blog-4912226416400969049.post-3471376251848229299</id><published>2011-09-21T14:33:00.001+01:00</published><updated>2011-09-21T14:34:11.269+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-21T14:34:11.269+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="IIS" /><title>How to install IIS (7.5) on Windows Server 2008 R2</title><content type="html">1. Open &lt;b&gt;Server Manager&lt;/b&gt;&lt;br /&gt;
2. Select &lt;i&gt;Roles&lt;/i&gt;; right click -&gt; &lt;i&gt;Add Roles&lt;/i&gt; and &lt;b&gt;Add Roles Wizard&lt;/b&gt; appears&lt;br /&gt;
3. In Add Roles Wizard: select &lt;i&gt;Web Server (IIS)&lt;/i&gt; in Server Roles page and click &lt;i&gt;Next&lt;/i&gt;&lt;br /&gt;
4. In Role Services page: select desired services (e.g. &lt;i&gt;ISAPI extensions&lt;/i&gt; if IIS should host Axis2/C web service). Click &lt;i&gt;Next&lt;/i&gt;.&lt;br /&gt;
5. Summary of role features and services that will be installed is displayed. Click &lt;i&gt;Install&lt;/i&gt;.&lt;br /&gt;
&lt;br /&gt;
Upon successful installation, a new node named &lt;b&gt;Web Server (IIS)&lt;/b&gt; should appear under &lt;b&gt;Roles&lt;/b&gt; in Server Manager.&lt;br /&gt;
&lt;br /&gt;
No restart is needed and IIS service will start running automatically. To test whether IIS works, type &lt;i&gt;http://localhost/&lt;/i&gt; in your browser. IIS7 Welcome picture(png) should appear.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4912226416400969049-3471376251848229299?l=bojan-komazec.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/b5Rs4Hd1Cjvk1-ETn7zX_fbTuI8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/b5Rs4Hd1Cjvk1-ETn7zX_fbTuI8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/b5Rs4Hd1Cjvk1-ETn7zX_fbTuI8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/b5Rs4Hd1Cjvk1-ETn7zX_fbTuI8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/MyPublicNotepad/~4/XH-b0RQdeZM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://bojan-komazec.blogspot.com/feeds/3471376251848229299/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4912226416400969049&amp;postID=3471376251848229299" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/3471376251848229299?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/3471376251848229299?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyPublicNotepad/~3/XH-b0RQdeZM/how-to-install-iis-75-on-windows-server.html" title="How to install IIS (7.5) on Windows Server 2008 R2" /><author><name>Bojan Komazec</name><uri>https://profiles.google.com/117174187628268281803</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total><feedburner:origLink>http://bojan-komazec.blogspot.com/2011/09/how-to-install-iis-75-on-windows-server.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUACQn46fyp7ImA9WhdVFk0.&quot;"><id>tag:blogger.com,1999:blog-4912226416400969049.post-406773419625339280</id><published>2011-09-21T13:22:00.001+01:00</published><updated>2011-09-21T13:22:43.017+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-21T13:22:43.017+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Computer architecture" /><title>How to get processor architecture information on Windows</title><content type="html">Is your machine 32-bit or 64-bit?&lt;br /&gt;
&lt;br /&gt;
One way of getting this information is reading &lt;b&gt;PROCESSOR_ARCHITECTURE&lt;/b&gt; value which can be found in  Windows Registry at this location: &lt;b&gt;HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment&lt;/b&gt;. &lt;br /&gt;
&lt;br /&gt;
This value on my 32-bit Intel machine is &lt;b&gt;x86&lt;/b&gt; and on another 64-bit machine with Intel Xeon processor is &lt;b&gt;AMD64&lt;/b&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4912226416400969049-406773419625339280?l=bojan-komazec.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ZKbUBm4R3bdy3C4dHzQXHvPszmo/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ZKbUBm4R3bdy3C4dHzQXHvPszmo/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ZKbUBm4R3bdy3C4dHzQXHvPszmo/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ZKbUBm4R3bdy3C4dHzQXHvPszmo/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/MyPublicNotepad/~4/qOwWRIjsBio" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://bojan-komazec.blogspot.com/feeds/406773419625339280/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4912226416400969049&amp;postID=406773419625339280" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/406773419625339280?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/406773419625339280?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyPublicNotepad/~3/qOwWRIjsBio/how-to-get-processor-architecture.html" title="How to get processor architecture information on Windows" /><author><name>Bojan Komazec</name><uri>https://profiles.google.com/117174187628268281803</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://bojan-komazec.blogspot.com/2011/09/how-to-get-processor-architecture.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0UBSXwyfyp7ImA9WhdUGUw.&quot;"><id>tag:blogger.com,1999:blog-4912226416400969049.post-6703683087102795740</id><published>2011-09-21T12:48:00.003+01:00</published><updated>2011-10-06T17:40:58.297+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-06T17:40:58.297+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Computer architecture" /><title>64-bit vs 32-bit</title><content type="html">Processors, installed operating systems and applications can be 32-bit or 64-bit. OS needs processor support (64-bit OS requires 64-bit processor) and Application needs operating system support (64-bit application requires 64-bit OS). Backwards compatibility is preserved (32-bit OS runs on 64-bit processor; 32-bit application runs on 64-bit OS).&lt;br /&gt;
&lt;br /&gt;
Here is a short review of all possible combinations:&lt;br /&gt;
&lt;br /&gt;
&lt;table border="2"&gt;&lt;tr&gt; &lt;td rowspan="2"&gt;&lt;/td&gt; &lt;td rowspan="2"&gt;&lt;/td&gt; &lt;td colspan="2"&gt;Operating System&lt;/td&gt; &lt;td rowspan="2"&gt;&lt;/td&gt; &lt;td rowspan="2"&gt;&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td align=center&gt;32&lt;/td&gt; &lt;td align=center&gt;64&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td rowspan="4"&gt;P&lt;br /&gt;
r&lt;br /&gt;
o&lt;br /&gt;
c&lt;br /&gt;
&lt;/td&gt; &lt;td rowspan="2"&gt;32&lt;/td&gt; &lt;td align=center&gt;OK&lt;/td&gt; &lt;td align=center&gt;x&lt;/td&gt; &lt;td&gt;32&lt;/td&gt; &lt;td rowspan="4"&gt;A&lt;br /&gt;
p&lt;br /&gt;
p&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td align=center&gt;x&lt;/td&gt; &lt;td align=center&gt;x&lt;/td&gt; &lt;td rowspan="2"&gt;64&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td rowspan="2"&gt;64&lt;/td&gt; &lt;td align=center&gt;x&lt;/td&gt; &lt;td align=center&gt;OK&lt;/td&gt; &lt;/tr&gt;
&lt;tr&gt; &lt;td align=center&gt;OK&lt;/td&gt; &lt;td align=center&gt;OK&lt;/td&gt; &lt;td&gt;32&lt;/td&gt; &lt;/tr&gt;
&lt;/table&gt;&lt;br /&gt;
Backward compatibility is not preserved in kernel mode: 32-bit drivers won't work on 64-bit OS!&lt;br /&gt;
&lt;br /&gt;
&lt;div dir="ltr" trbidi="on"&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;32-bit applications can run both on 32-bit and 64-bit operating systems.&amp;nbsp;64-bit Windows OS uses WoW64 emulation layer to support executing 32-bit applications which are, by default, installed in C:\Program Files (x86) directory, load 32-bit libraries from C:\Windows\SysWOW64 and use HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node portion of the registry.&lt;/li&gt;
&lt;/ul&gt;&lt;ul style="text-align: left;"&gt;&lt;li&gt;64-bit applications can run only on 64-bit operating systems. It is possible to run 64-bit operating system on (physically) 32-bit machine (by using some of Virtual Machines, e.g. Oracle's VirtualBox).&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
It is possible to build applications that target 64-bit architectures on 32-bit hosts. This process is called &lt;b&gt;cross-compiling&lt;/b&gt;.&lt;br /&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4912226416400969049-6703683087102795740?l=bojan-komazec.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/UFRW13iTTuaQ4xtfcgtuC9_mTSA/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/UFRW13iTTuaQ4xtfcgtuC9_mTSA/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/UFRW13iTTuaQ4xtfcgtuC9_mTSA/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/UFRW13iTTuaQ4xtfcgtuC9_mTSA/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/MyPublicNotepad/~4/l980BrJrwvk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://bojan-komazec.blogspot.com/feeds/6703683087102795740/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4912226416400969049&amp;postID=6703683087102795740" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/6703683087102795740?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/6703683087102795740?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyPublicNotepad/~3/l980BrJrwvk/64-bit-vs-32-bit.html" title="64-bit vs 32-bit" /><author><name>Bojan Komazec</name><uri>https://profiles.google.com/117174187628268281803</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://bojan-komazec.blogspot.com/2011/09/64-bit-vs-32-bit.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0UGRH0ycCp7ImA9WhdVFUQ.&quot;"><id>tag:blogger.com,1999:blog-4912226416400969049.post-7316932765036827013</id><published>2011-09-21T11:00:00.000+01:00</published><updated>2011-09-21T11:00:25.398+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-21T11:00:25.398+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="DOS" /><category scheme="http://www.blogger.com/atom/ns#" term="Batch file" /><title>DOS script which outputs directory contents into a txt file</title><content type="html">This simple batch file prints out (recursively, including subdirectories) the content of the current directory into a text file:&lt;br /&gt;
&lt;br /&gt;
list_all_files.bat:&lt;br /&gt;
&lt;div class="my_code"&gt;dir /b /s * &gt;temp.txt&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;dir *&lt;/b&gt; lists the content of the current directory. &lt;b&gt;/b&lt;/b&gt; switch makes it to use bare format (report does not include heading information or summary). &lt;b&gt;/s&lt;/b&gt; instructs it to use recursion. &lt;b&gt;&gt;temp.txt&lt;/b&gt; instructs it to output report to temp.txt file.&lt;br /&gt;
&lt;br /&gt;
After running it, this is the content of temp.txt:&lt;br /&gt;
&lt;div class="file_hierarchy"&gt;C:\test\list_all_files.bat&lt;br /&gt;
C:\test\mydir&lt;br /&gt;
C:\test\temp.txt&lt;br /&gt;
C:\test\mydir\a.txt&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
Links and references:&lt;br /&gt;
&lt;a href="http://www.computerhope.com/dirhlp.htm"&gt;Microsoft DOS dir command&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4912226416400969049-7316932765036827013?l=bojan-komazec.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/bkr10yZQEhKQfuidWtScVXZBDqQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/bkr10yZQEhKQfuidWtScVXZBDqQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/bkr10yZQEhKQfuidWtScVXZBDqQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/bkr10yZQEhKQfuidWtScVXZBDqQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/MyPublicNotepad/~4/PSH974FQTU4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://bojan-komazec.blogspot.com/feeds/7316932765036827013/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4912226416400969049&amp;postID=7316932765036827013" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/7316932765036827013?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/7316932765036827013?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyPublicNotepad/~3/PSH974FQTU4/dos-script-which-outputs-directory.html" title="DOS script which outputs directory contents into a txt file" /><author><name>Bojan Komazec</name><uri>https://profiles.google.com/117174187628268281803</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://bojan-komazec.blogspot.com/2011/09/dos-script-which-outputs-directory.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkMBRn08fCp7ImA9WhdVFEk.&quot;"><id>tag:blogger.com,1999:blog-4912226416400969049.post-5744141654725861308</id><published>2011-09-19T14:53:00.001+01:00</published><updated>2011-09-19T14:54:17.374+01:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-19T14:54:17.374+01:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="MFC" /><category scheme="http://www.blogger.com/atom/ns#" term="C++" /><category scheme="http://www.blogger.com/atom/ns#" term="GUI" /><title>Message only window (MFC)</title><content type="html">&lt;div dir="ltr" style="text-align: left;" trbidi="on"&gt;As expected: &lt;a href="http://msdn.microsoft.com/en-us/library/ms632599(VS.85).aspx#message_only"&gt;message only window&lt;/a&gt; cannot post messages to its "parent". &lt;a href="http://msdn.microsoft.com/en-us/library/9tdesxec.aspx"&gt;CWnd::PostMessage()&lt;/a&gt; invoked on HWND_MESSAGE crashes with access violation:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="my_code"&gt;class CMsgOnlyWnd : public CWnd&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; &amp;nbsp;...&lt;br /&gt;
public:&lt;br /&gt;
&amp;nbsp; &amp;nbsp;Initialize();&lt;br /&gt;
&amp;nbsp; &amp;nbsp;SendMsgToParent();&lt;br /&gt;
&amp;nbsp; &amp;nbsp;...&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
CMsgOnlyWnd::Initialize()&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; &amp;nbsp;...&lt;br /&gt;
&amp;nbsp; &amp;nbsp;CreateEx(0, ::AfxRegisterWndClass(NULL), "MsgOnlyWnd", 0, 0, 0, 0, 0,    HWND_MESSAGE, 0, NULL);&lt;br /&gt;
&amp;nbsp; &amp;nbsp;...&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
CMsgOnlyWnd::SendMsgToParent()&lt;br /&gt;
{&lt;br /&gt;
&amp;nbsp; &amp;nbsp;GetParent()-&amp;gt;PostMessage(...);   &lt;br /&gt;
}&lt;/div&gt;&lt;br /&gt;
Links and references:&lt;br /&gt;
&lt;a href="http://msdn.microsoft.com/en-us/library/ms632599(VS.85).aspx#message_only"&gt;Message-Only Windows (MSDN)&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.codeproject.com/KB/dialog/messageonly.aspx"&gt;How to make a Message Only Window&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://stackoverflow.com/questions/2122506/how-to-create-a-hidden-window-in-c"&gt;How to create a hidden window in C++&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4912226416400969049-5744141654725861308?l=bojan-komazec.blogspot.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/AF4HlLDqHh6IZ3V20frJNsMw4xY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/AF4HlLDqHh6IZ3V20frJNsMw4xY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/AF4HlLDqHh6IZ3V20frJNsMw4xY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/AF4HlLDqHh6IZ3V20frJNsMw4xY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/MyPublicNotepad/~4/BDulMktvfMo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://bojan-komazec.blogspot.com/feeds/5744141654725861308/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=4912226416400969049&amp;postID=5744141654725861308" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/5744141654725861308?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/4912226416400969049/posts/default/5744141654725861308?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/MyPublicNotepad/~3/BDulMktvfMo/message-only-window-mfc.html" title="Message only window (MFC)" /><author><name>Bojan Komazec</name><uri>https://profiles.google.com/117174187628268281803</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://bojan-komazec.blogspot.com/2011/09/message-only-window-mfc.html</feedburner:origLink></entry></feed>

