Log4cpp 是 Log4J 的 C++ 移植版本,開放源代碼並且完全免費。與 Log4J 能夠跨平臺一樣,Log4cpp 也致力於寫出跨平臺的 C++ 程序。Log4cpp 主要是用於 C++ 程序中寫 log 文件,與此同時,Log4cpp 中有很多有用的類庫,對於寫跨平臺 C++ 程序的人來說,可以直接拿來用,或者作爲自己寫跨平臺類的參考。
Log4cpp 中的跨平臺類庫有明顯的 Java 痕跡,比如 Class、Object 、Loader、Locale 等類。 Log4cpp 中的類都可以根據類名 new 出一個 instance,其實現的方式和 MFC 如出一轍:通過 C++ 強大的宏來實現。
Log4cpp 中的跨平臺類庫主要有:
信號類:Condition(broadcast,signal,wait),CriticalSection(lock,unlock),WaitAccess,Event(set,reset,wait),Mutex(lock,unlock),Semaphore(wait,tryWait,post)
網絡類:InetAddress,Socket,ServerSocket,DatagramSocket,SocketInputStream,SocketOutputStream
日期類:DateFormat,DateTimeDateFormat,System(currentTimeMillis)
文件類:FileWatchdog(doOnChange)
內存操作類:基於引用計數機制的智能指針 ObjectPtrT
字符串操作類:StrictMath,StringHelper(toUpperCase,toLowerCase,trim,equalsIgnoreCase,endsWith,format),StringTokenizer
線程類:Thread(start,run,join)
使用以上的類不用考慮 thread handle, event handle, socket handle 之類的 handle 問題,所有這些文件已經被封裝了。很好用,對不對?
不足之處在於沒有 GUI 類。ANSI C++ 中對於目錄等文件系統的處理功能較弱,這裏面也沒有目錄處理類。另外Socket 的 read(void * buf, size_t len) 不能設置 timeout,並且如果讀取數據個數小於 len 那麼 read 函數將一直堵塞,不太好用,很可惜。實際的使用上面,可以考慮做一個 Socket 子類,重寫 read() 函數。
以下是一個示例程序,在 VC6 下編譯運行通過,代碼中有中文全角空格。
#include "stdafx.h" #include #include using namespace log4cxx; using namespace log4cxx::helpers; #include #include using namespace std; class MyOutputer{ private: Mutex m_outputLock; public: void output(const char * msg){ m_outputLock.lock(); cout << msg << endl; m_outputLock.unlock(); } }; class MyThread : public Thread{ private: bool m_running; MyOutputer m_out; public: MyThread(){m_running = false; } virtual ~MyThread(){} virtual void run(){ m_running = true; //循環十次,執行十秒 for(int i =0; i < 10 && m_running; i++){ m_out.output("MyThread running..."); Thread::sleep(1000); } } void stop(){ m_running = false; }};typedef ObjectPtrT MyThreadPtr; int main(int argc, char* argv[]){ MyOutputer out; out.output("main begin..."); vector threadList; int count = 5, i=0; for(i =0; i< count; i++){ MyThread *pThread = new MyThread(); threadList.push_back(pThread); } out.output("main start all threads..."); for(i =0; i< count; i++){ MyThread *pThread = threadList[i]; Thread::sleep(300); pThread->start(); } out.output("main sleep 4 seconds...");
//等 4 秒,停止所有線程 Thread::sleep(4000); out.output("main stop all threads..."); for(i =0; i< count; i++){ MyThread *pThread = threadList[i]; pThread->stop(); } out.output("main wait all threads..."); //等待所有線程中止
for(i =0; i< count; i++){ MyThread *pThread = threadList[i]; pThread->join(); } threadList.clear(); //所有線程對象被啓動銷燬 out.output("main end"); return 0;}