Onega

a lot of VC++ posts, a few C# posts, and some miscellaneous stuff

Tuesday, November 22, 2005

http://spaces.msn.com/members/OnegaZhang

My MSN space
http://spaces.msn.com/members/OnegaZhang

Sunday, November 20, 2005

welcome to http://spaces.msn.com/members/OnegaZhang/

Welcome to http://spaces.msn.com/members/OnegaZhang/

C++ makefile and g++

#include < iostream >
using namespace std;

int main(void) {
cout << "welcome to www.fruitfruit.com" << endl ;
cout << "MinGW test" << endl;
return 0;
}
//~ set environment variables:
//~ C_INCLUDE_PATH = C:\MinGW\include
//~ CPLUS_INCLUDE_PATH = C:\mingw\include\c++\3.4.4;C:\mingw\include\c++\3.4.4\mingw32;C:\mingw\include\c++\3.4.4\backward;C:\mingw\include
//~ LIBRARY_PATH = C:\MinGW\lib
//~ PATH = C:\mingw\bin
//~ build command line:
//~ D:\test>g++ main.cpp -O3 -o hello
//~ makefile:
//~ all:
//~ g++ test1.cpp -g -o run

Wednesday, November 16, 2005

managed C++ notes

public ref class MyClass
{
public:
    static System::Guid MyClassGuid = *(gcnew Guid ("B6806700-E2B1-4022-9D4B-B0205CB37935"));
};

convert time_t to tm via gmtime/localtime, then you can refer to the this page.
http://lists.gnu.org/archive/html/dotgnu-pnet-commits/2003-02/msg00221.html
using System;
using System.Runtime.InteropServices;

__module
{

        // Get the current system time in UTC.
        public static long __syscall_utc_time()
                        {
                                return DateTime.UtcNow.Ticks;
                        }

        // Get the current system time in local time.
        public static long __syscall_local_time()
                        {
                                return DateTime.Now.Ticks;
                        }

        // Unpack a tick value into a "struct tm" structure.
        public static void __syscall_unpack_time
                                (long ticks, IntPtr tm, bool is_local)
                        {
                                DateTime dt;
                                if(is_local)
                                {
                                        long tz = __syscall_utc_time() -
__syscall_local_time();
                                        dt = new DateTime(ticks + tz);
                                }
                                else
                                {
                                        dt = new DateTime(ticks);
                                }
                                Marshal.WriteInt32(tm, 0, dt.Second);
                                Marshal.WriteInt32(tm, 4, dt.Minute);
                                Marshal.WriteInt32(tm, 8, dt.Hour);
                                Marshal.WriteInt32(tm, 12, dt.Day);
                                Marshal.WriteInt32(tm, 16, dt.Month - 1);
                                Marshal.WriteInt32(tm, 20, dt.Year - 1900);
                                Marshal.WriteInt32(tm, 24, (int)(dt.DayOfWeek));
                                Marshal.WriteInt32(tm, 28, dt.DayOfYear);
                                Marshal.WriteInt32(tm, 32, 0);  /* TODO -
tm_isdst */
                        }

} // __module

Tuesday, November 15, 2005

ACE multicast example with thread

//Server

#include "stdafx.h"
#include "ace_auto_link.h"
#define WIN32_LEAN_AND_MEAN        // Exclude rarely-used stuff from Windows headers

#include <stdio.h>
#include <tchar.h>
#include "ace/OS.h"
#include "ace/SOCK_Dgram.h"
#include "ace/INET_Addr.h"
#include "ace/log_msg.h"
#include "ace/SOCK_Dgram_Mcast.h"
#include "ace/get_opt.h"
#include "process.h"

#define ARRAY_SIZE(X) sizeof(X)/sizeof(X[0]) 
#ifndef __WFUNCTION__

    #define WIDEN2(x) L ## x 
    #define WIDEN(x) WIDEN2(x) 
    #define __WFILE__ WIDEN(__FILE__) 
    #define __WFUNCTION__ WIDEN(__FUNCTION__) 
    #ifdef _UNICODE 
        #define __TFILE__ __WFILE__ 
        #define __TFUNCTION__ __WFUNCTION__ 
    #else 
        #define __TFILE__ __FILE__ 
        #define __TFUNCTION__ __FUNCTION__ 
    #endif 
#endif //__WFUNCTION__


#define __STR2__(x) #x 
#define __STR1__(x) __STR2__(x) 
//#define __LOC__ __FILE__ "("__STR1__(__LINE__)") : Warning Msg: " 
#define __LOC2__ __FILE__ "("__STR1__(__LINE__)") " 
#define __FLOC__ __TFILE__ "("__STR1__(__LINE__)"): " 
#define __MLOC__ __TFUNCTION__ "("__STR1__(__LINE__)"): " 
const int PATH_LEN = 1024+MAX_PATH;

#define DEFAULT_MULTICAST_ADDR ACE_TEXT("224.9.9.2")
//#define TIMEOUT 5



class BaseThread

{
// To create a thread, inherit from BaseThread and implement run()
// To start thread, call start_thread()/start_threadex()
// Do not close the handle returned by start_threadex()/get_handle() in inherited class

// To stop thread, call stop(), the thread is actually stopped when is_stopped() return ture

public:
    BaseThread():m_working(true),m_stopped(false),m_return_code(0),m_thread_id(0)
        ,m_thread_handle(NULL)
    {}
    ~BaseThread()
    {
        if(m_thread_handle)
            CloseHandle(get_handle());
        m_thread_handle = NULL;
    }
    inline void start_thread()
    {
        start_threadex();
    }
    inline uintptr_t start_threadex()
    {
        return m_thread_handle = _beginthreadex( NULL, 0, &ExThreadProc, this, 0, &m_thread_id );
    }
    virtual long run() =0;
    inline void stop()
    {// tell the thread to stop

        m_working = false;
    }
    inline bool is_stopped()
    {// if the thread is actually stopped

        return m_stopped;
    }
    inline long get_return_code()
    {// the value returned by run()
        return m_return_code;
    }
    inline HANDLE get_handle()
    {
        return reinterpret_cast<HANDLE>(m_thread_handle); 
    }
    inline bool is_working()
    {// run() shall check this value

        return m_working;
    }
private:
    static void __cdecl BasicThreadProc( void* pArguments )
    {//http://fruitfruit.blogspot.com/2005_05_01_fruitfruit_archive.html

        ExThreadProc(pArguments);
    } 
    static unsigned __stdcall ExThreadProc( void* pArguments )
    {//http://fruitfruit.blogspot.com/2005_05_01_fruitfruit_archive.html

        BaseThread* pb = reinterpret_cast<BaseThread*>(pArguments);
        pb->m_return_code = pb->run();
        pb->stop();
        pb->m_stopped = true;
        _endthreadex( 0 );
        return 0;
    }
    volatile bool m_stopped;
    long m_return_code;
    uintptr_t m_thread_handle;
    unsigned m_thread_id;
    volatile bool m_working;
};

//The following class is used to receive multicast messages from

//any sender.
class Receiver_Multicast:public BaseThread

{
public:
    Receiver_Multicast(int port):
      m_multicast_addr(port,DEFAULT_MULTICAST_ADDR),m_remote_addr((u_short)0)
          ,recv_timeout(1)
      {
          // Subscribe to multicast address.
          if (mcast_dgram_.subscribe (m_multicast_addr) == -1)
          {
              //ACE_DEBUG((LM_DEBUG,ACE_TEXT("Error in subscribing to Multicast address \n")));
              exit(-1);
          }
      }
      ~Receiver_Multicast()
      {
          mcast_dgram_.close();
          //if(mcast_dgram_.unsubscribe()==-1)
             // ACE_DEBUG((LM_ERROR,"Error in unsubscribing from Mcast group\n"));
      }
      //Receive data from someone who is sending data on the multicast group

      //address. To do so it must use the multicast datagram component

      //mcast_dgram_.
      int recv_multicast()
      {
          //get ready to receive data from the sender.
          ACE_Time_Value ace_recv_timeout (recv_timeout);
          if(mcast_dgram_.recv (&mcast_info,sizeof (mcast_info),m_remote_addr,0,&ace_recv_timeout)==-1)
          {
              ACE_DEBUG((LM_DEBUG,ACE_TEXT("(%P|%t) %s end, received NOTHING*****\n"),__TFUNCTION__));
              return -1;
          }
          else

          {
              ACE_UINT32 ip = m_remote_addr.get_ip_address();
              TCHAR ipbuf[64] = {0};
              _stprintf( ipbuf, _T("%d.%d.%d.%d"), (ip>>24)&255, (ip>>16)&255, (ip>>8)&255, ip&255 ); 
              ACE_TCHAR host_name_buf[64] = {0};
              m_remote_addr.get_host_name(host_name_buf, ARRAY_SIZE(host_name_buf));
              ACE_DEBUG ((LM_DEBUG, ACE_TEXT("(%P|%t) Received multicast from {%s, %s}:%d.\n"),
                  host_name_buf, ipbuf, m_remote_addr.get_port_number()));
              ACE_DEBUG((LM_DEBUG,ACE_TEXT("Successfully received %d\n"), mcast_info));
              ACE_DEBUG((LM_DEBUG,ACE_TEXT("(%P|%t) %s end\n"),__TFUNCTION__));
              return 0;
          }
      }
    long run( )
    {
        while( is_working())
        {
            if(m_multicast_addr.get_port_number()>0)
            {
                recv_multicast();
            }
            Sleep(1000);
        }
        ACE_DEBUG((LM_DEBUG,ACE_TEXT("(%P|%t) %s end\n"),__TFUNCTION__));
        return 0;
    } 
    void set_recv_timeout(int v)
    {
        if(v>0)
        recv_timeout = v;
    }
private:
    ACE_INET_Addr m_multicast_addr;
    ACE_INET_Addr m_remote_addr;
    ACE_SOCK_Dgram_Mcast mcast_dgram_;
    int mcast_info;
    int recv_timeout;
};

class Sender_Multicast:public BaseThread

{
public:
    Sender_Multicast(int port):
      local_addr_((u_short)0),dgram_(local_addr_),
          multicast_addr_(port,DEFAULT_MULTICAST_ADDR)
      {
      }
      //Method which uses a simple datagram component to send data to the //multicast group.
      int send_to_multicast_group()
      {
          //Convert the information we wish to send into network byte order

          mcast_info= htons (1000);
          // Send multicast

          if(dgram_.send (&mcast_info, sizeof (mcast_info), multicast_addr_)==-1)
          {
              ACE_DEBUG((LM_ERROR,ACE_TEXT("Send to Multicast group failed \n")));
              return -1;
          }
          ACE_DEBUG ((LM_DEBUG,
              ACE_TEXT("%s: Sent multicast to group. Number sent is %d.\n"),
              __TFUNCTION__,
              mcast_info));
          return 0;
      }
    long run(  )
    {
        while( this->is_working())
        {
            if(this->multicast_addr_.get_port_number()>0)
            {
                this->send_to_multicast_group();
            }
            Sleep(7000);
        }
        ACE_DEBUG((LM_DEBUG,ACE_TEXT("(%P|%t) %s end\n"),__TFUNCTION__));
        return 0;
    } 
private:
    ACE_INET_Addr multicast_addr_;
    ACE_INET_Addr local_addr_;
    ACE_SOCK_Dgram dgram_;
    int mcast_info;
};


int ACE_TMAIN(int argc, TCHAR* argv[])
{
    ACE_DEBUG((LM_DEBUG,ACE_TEXT("(%P|%t) %s starts\n"),__TFUNCTION__));
    Sender_Multicast sender_thread(2000);
    Receiver_Multicast recv_thread(2000);
    sender_thread.start_thread();
    recv_thread.start_thread();
    getchar();
    sender_thread.stop();
    recv_thread.stop();
    while( sender_thread.is_stopped() == false 
        || recv_thread.is_stopped() == false)
    {
        Sleep(1);
    }
    ACE_DEBUG((LM_DEBUG,ACE_TEXT("(%P|%t) %s end\n"),__TFUNCTION__));
    return 0;
}

ACE unicode version with VC8

change project properties
Project-->ACE Properties...
Configuration Properties-->General:
Character Set : Use Unicode Character Set
C/C++-->Preprocessor:
Preprocessor Definitioins: ACE_USES_WCHAR
C/C++-->Language
Treat wchar_t as Built-in Type: Yes (/Zc:wchar_t)

ACE client application should do the same work to build unicode version.

ace/os.h must be included before windows.h

ACE multicast sender and receiver

//Server

#include "stdafx.h"

#include "ace/OS.h"

#include "ace/SOCK_Dgram.h"

#include "ace/INET_Addr.h"

#include "ace/log_msg.h"

#include "ace/SOCK_Dgram_Mcast.h"

#ifdef _DEBUG

#pragma comment(lib,"D:\\ACE\\ACE_wrappers\\lib\\aced.lib")

#else

#pragma comment(lib,"D:\ACE\ACE_wrappers\lib\ace.lib")

#endif

#define DEFAULT_MULTICAST_ADDR "224.9.9.2"

#define TIMEOUT 5

//The following class is used to receive multicast messages from

//any sender.

class Receiver_Multicast

{

public:

    Receiver_Multicast(int port):

      mcast_addr_(port,DEFAULT_MULTICAST_ADDR),remote_addr_((u_short)0)

      {

          // Subscribe to multicast address.

          if (mcast_dgram_.subscribe (mcast_addr_) == -1)

          {

              ACE_DEBUG((LM_DEBUG,"Error in subscribing to Multicast address \n"));

              exit(-1);

          }

      }

      ~Receiver_Multicast()

      {

          if(mcast_dgram_.unsubscribe()==-1)

              ACE_DEBUG((LM_ERROR,"Error in unsubscribing from Mcast group\n"));

      }

      //Receive data from someone who is sending data on the multicast group

      //address. To do so it must use the multicast datagram component

      //mcast_dgram_.

      int recv_multicast()

      {

          //get ready to receive data from the sender.

          if(mcast_dgram_.recv (&mcast_info,sizeof (mcast_info),remote_addr_)==-1)

              return -1;

          else

          {

              ACE_DEBUG ((LM_DEBUG, "(%P|%t) Received multicast from %s:%d.\n",

                  remote_addr_.get_host_name(), remote_addr_.get_port_number()));

              ACE_DEBUG((LM_DEBUG,"Successfully received %d\n", mcast_info));

              return 0;

          }

      }

private:

    ACE_INET_Addr mcast_addr_;

    ACE_INET_Addr remote_addr_;

    ACE_SOCK_Dgram_Mcast mcast_dgram_;

    int mcast_info;

};



class Sender_Multicast

{

public:

    Sender_Multicast(int port):

      local_addr_((u_short)0),dgram_(local_addr_),

          multicast_addr_(port,DEFAULT_MULTICAST_ADDR)

      {

      }

      //Method which uses a simple datagram component to send data to the //multicast group.

      int send_to_multicast_group()

      {

          //Convert the information we wish to send into network byte order

          mcast_info= htons (1000);

          // Send multicast

          if(dgram_.send (&mcast_info, sizeof (mcast_info), multicast_addr_)==-1)

              return -1;

          ACE_DEBUG ((LM_DEBUG,

              "%s; Sent multicast to group. Number sent is %d.\n",

              __FILE__,

              mcast_info));

          return 0;

      }

private:

    ACE_INET_Addr multicast_addr_;

    ACE_INET_Addr local_addr_;

    ACE_SOCK_Dgram dgram_;

    int mcast_info;

};

int send_multicast_main(int argc, char*argv[])

{

    Sender_Multicast m(2000);

    if(m.send_to_multicast_group()==-1)

    {

        ACE_DEBUG((LM_ERROR,"Send to Multicast group failed \n"));

        exit(-1);

    }

    else

        ACE_DEBUG((LM_DEBUG,"Send to Multicast group successful \n"));

    return 0;

}

int Receiver_Multicast_main(int argc, char*argv[])

{

    Receiver_Multicast m(2000);

    while(m.recv_multicast()!=-1)

    {

        ACE_DEBUG((LM_DEBUG,"Multicaster successful \n"));

    }

    ACE_DEBUG((LM_ERROR,"Multicaster failed \n"));

    exit(-1);

    return 0;

}

int main(int argc, char* argv[])

{

    return send_multicast_main(argc,argv);

    return Receiver_Multicast_main(argc,argv);

}

ACE broadcast sender and receiver

// ACE broadcast sample

// the following command run the program as server: argv[0] 1234 -s

// the following command run the program as client: argv[0] 1234 -c

#include "stdafx.h"

#include "ace/SOCK_Dgram_Bcast.h"

#include "ace/INET_Addr.h"

#include "ace/log_msg.h"

#include "ace/OS_NS_string.h"

#include "ace/OS.h"



#ifdef _DEBUG

#pragma comment(lib,"D:\\ACE\\ACE_wrappers\\lib\\aced.lib")

#else

#pragma comment(lib,"D:\ACE\ACE_wrappers\lib\ace.lib")

#endif



u_short PORT = ACE_DEFAULT_SERVER_PORT;

#define DATA_BUFFER_SIZE 1024

#define SIZE_DATA 256

class Server

{

public:

    Server(int local_port)

        :local_addr_(local_port),local_(local_addr_),data_buf(NULL)

    {

        data_buf = new char[DATA_BUFFER_SIZE];

    }

    //Expect data to arrive from the remote machine. Accept it and display

    //it. After receiving data, immediately send some data back to the

    //remote.

    int accept_data()

    {

        int byte_count=0;

        while( (byte_count=local_.recv(data_buf,SIZE_DATA,remote_addr_))!=-1)

        {

            data_buf[byte_count]=0;

            ACE_DEBUG((LM_DEBUG, "Data received from remote %s was %s \n"

                ,remote_addr_.get_host_name(), data_buf));

            ACE_OS::sleep(1);

            if(send_data()==-1) break;

        }

        return -1;

    }

    //Method used to send data to the remote using the datagram component

    //local_

    int send_data()

    {

        ACE_DEBUG((LM_DEBUG,"Preparing to send reply to client %s:%d\n",

            remote_addr_.get_host_name(),remote_addr_.get_port_number()));

        ACE_OS::sprintf(data_buf,"Server(www.fruitfruit.com) greets you");

        if( local_.send(data_buf, ACE_OS::strlen(data_buf)+1,remote_addr_)==-1)

            return -1;

        else

            return 0;

    }

private:

    char *data_buf;

    ACE_INET_Addr remote_addr_;

    ACE_INET_Addr local_addr_;

    ACE_SOCK_Dgram local_;

};

int

main (int argc,char *argv[])

{

    if(argc<3)

    {

        ACE_DEBUG((LM_DEBUG,"Usage: %s <Port Number> -s | -c\n", argv[0]));

        ACE_OS::exit(1);

    }

    PORT = ACE_OS::atoi(argv[1]);

    if( ACE_OS::strstr(argv[2],"s") || ACE_OS::strstr(argv[2], "S"))

    {

        ACE_DEBUG((LM_DEBUG,"(%P|%t) %s listens on port %d\n",argv[0], PORT));

        Server server(PORT);

        server.accept_data();

    }

    else

    {

        ACE_DEBUG((LM_DEBUG,"(%P|%t) %s broadcasts to port %d\n",argv[0], PORT));

        ACE_INET_Addr local ((u_short) 0);

        /* Instead of creating the ACE_SOCK_Dgram we created last time,

        we'll create an ACE_SOCK_Dgram_Bcast.  "Bcast" means, of course,

        "Broadcast".  This ACE object is clever enough to go out to the OS

        and find all of the network interfaces.  When you send() on a

        Dgram_Bcast, it will send the datagram out on all of those

        interfaces.  This is quiet handy if you do it on a multi-homed

        host that plays router...  */

        ACE_SOCK_Dgram_Bcast dgram;

        if (dgram.open (local) == -1)

            ACE_ERROR_RETURN ((LM_ERROR,

            "%p\n",

            "datagram open"),

            -1);

        char buf[BUFSIZ];

        sprintf (buf, "Wecome to www.fruitfruit.com!");

        /* The only other difference between us and the directed client is

        that we don't specify a host to receive the datagram.  Instead, we

        use the magic value "INADDR_BROADCAST".  All hosts are obliged to

        respond to datagrams directed to this address the same as they

        would to datagrams sent to their hostname.

        Remember, the Dgram_Bcast will send a datagram to all interfaces

        on the host.  That's true even if the address is for a specific

        host (and the host address makes sense for the interface).  The

        real power is in using an INADDR_BROADCAST addressed datagram

        against all interfaces.  */

        ACE_INET_Addr remote (PORT,INADDR_BROADCAST);

        ACE_DEBUG ((LM_DEBUG,

            "(%P|%t) Sending (%s) to the server.\n",

            buf));

        if (dgram.send (buf,

            ACE_OS::strlen (buf) + 1,

            remote) == -1)

            ACE_ERROR_RETURN ((LM_ERROR,

            "%p\n",

            "send"),

            -1);

        if (dgram.recv (buf,

            sizeof (buf),

            remote) == -1)

            ACE_ERROR_RETURN ((LM_ERROR,

            "%p\n",

            "recv"),

            -1);

        ACE_DEBUG ((LM_DEBUG,

            "(%P|%t) The server said:  %s\n",

            buf));

        /* Using the "remote" object instance, find out where the server

        lives.  We could then save this address and use directed datagrams

        to chat with the server for a while.  */

        ACE_DEBUG ((LM_DEBUG,

            "(%P|%t) The server can be found at:  (%s:%d)\n",

            remote.get_host_name(),

            PORT));

    }

    ACE_DEBUG((LM_DEBUG,"(%P|%t) %s end\n",argv[0]));

    return 0;

}

Monday, November 14, 2005

build boost 1.33 (regex) with VC8.0 (VC++ 2005)

Follow these steps to build boost:
# Download "boost_1_33_0.exe" from SourceForge.org
# Download "boost-jam-3.1.11-1-ntx86.zip" from SourceForge.org
# Extract "boost_1_33_0.exe" and "boost-jam-3.1.11-1-ntx86.zip"
# "Start" → "All Programs" → "Microsoft Visual Studio 2005" → "Visual Studio Tools" → "Visual Studio 2005 Command Prompt"
# Change Directory to "boost_1_33_0.exe" extraction directory.
# TYPE$ bjam "-sTOOLS=vc-8_0" install

I got the following result:
...failed updating 6 targets...
...skipped 28 targets...
...updated 4777 targets...

The biggest problem is that boost regex library is not created.

try again:
D:\boost\boost_1_33_0>bjam "-sTOOLS=vc-8_0" install > vc8_log.txt

boost regex library still failed. But I get some clue from the log file.

From Onega (www.fruitfruit.com, http://fruitfruit.blogspot.com/)
Start-->All Programs-->Control Panel-->Regional and Language Options:
Advanced tab:
Select a language to match the language version of the non-Unicode programs you want to use:
English (United States)

Restart computer and try again:
D:\boost\boost_1_33_0>bjam "-sTOOLS=vc-8_0" install > vc8_log.txt
OK, I got it.
FileClone C:\Boost\lib\libboost_regex-vc80-mt-1_33.lib
FileClone C:\Boost\lib\boost_serialization-vc80-mt-gd-1_33.lib
FileClone C:\Boost\lib\boost_wserialization-vc80-mt-gd-1_33.lib
HardLink C:\Boost\lib\boost_filesystem-vc80-mt-gd.lib
HardLink C:\Boost\lib\boost_regex-vc80-mt-gd.lib
HardLink C:\Boost\lib\boost_regex-vc80-mt.lib
HardLink C:\Boost\lib\libboost_regex-vc80-mt-sgd.lib
HardLink C:\Boost\lib\libboost_regex-vc80-mt-gd.lib
HardLink C:\Boost\lib\libboost_regex-vc80-mt-s.lib
HardLink C:\Boost\lib\libboost_regex-vc80-mt.lib
HardLink C:\Boost\lib\boost_serialization-vc80-mt-gd.lib
HardLink C:\Boost\lib\boost_wserialization-vc80-mt-gd.lib
...updated 40 targets...