1. 程式人生 > >POCO文檔翻譯:POCO C++庫入門指南

POCO文檔翻譯:POCO C++庫入門指南

配置 air direct nic 目錄 示例 中斷處理 取消 驗證

內容目錄

介紹

Foundation庫

XML庫

Util庫

Net庫

將這些東西組合到一起

介紹

POCO C++庫是一組開源C++類庫的集合,它們簡化及加速了用C++來開發以網絡功能為核心的可移植程序的過程。這些庫,完美地與C++標準庫結合到一起,並且填補了它所留下的那些空缺。它們具有模塊化、高效的設計與實現,使得POCO C++庫特別適合於進行嵌入式開發。而這是C++編程語言正在變得越來越流行的領域,因為,它既能進行底層(設備I/O、中斷處理,等等)的開發,也能進行高級的面向對象的開發。當然,POCO也已經準備好面對企業級開發的挑戰了。

技術分享

POCO由4個核心庫及若幹個附加庫組成。核心庫是:Foundation、XML、Util和Net。其中的兩個附加庫是:NetSSL,為Net 庫中的網絡類提供SSL 支持;Data,用來以統一的形式訪問不同的SQL 數據庫。POCO致力於進行以網絡功能為核心的跨平臺C++軟件的開發,可以類比於Ruby on Rails對於Web開發的作用——一個功能強大而又簡單易用的平臺,用來構建妳自己的應用程序。POCO是嚴格圍繞標準ANSI/ISO C++來開發的,並且支持標準庫。貢獻者們努力地達到以下要素之間的平衡:使用高級的C++特性;保持那些類的可理解性;保持代碼的幹凈、一致及易維護性。

Foundation

Foundation 庫是 POCO 的心臟。 它包含著:底層平臺 的抽象層;常用 的輔助類和函數。 Foundation 庫包含:定義 了固定尺寸整數的類型; 將整數在不同的字節序之間轉換的函數; 一個 Poco::Any 類(基於 boost::Any );用於錯誤處理 及調試的工具,包括各種各樣的異常 類及斷言支持。 還有: 一些用於內存管理的類,包括基於引用計數 的智能指針,以及一些用於緩沖區管理的類,還有內存池。對於字符串處理 POCO包含 一些函數,可做以下事情 :修剪字符串 ;進行大小 寫不敏感的比較;進行大小寫轉換。 還利用一些類提供了基本的 Unicode文字支持 這些類能夠將文字 在不同的字符編碼之間轉換,包括 UTF-8 UTF-16 還提供了 對於數字 的格式化和解析功能的支持,包括一個類型安全的sprintf 變種。 還提供了以著名的PCRE 庫( http://www.pcre.org

)為基礎的正則表達式支持。

POCO提供 了一些類,用於處理多種變種中的日期及時間。對於文件系統訪問功能 POCO提供 Poco::File Poco::Path 類,以及 Poco::DirectoryIterator 類。 在狠多程序中,某個部分需要向其它部分告知某些事件發生了 POCO提供 Poco::NotificationCenter Poco::NotificationQueue 和事件 (類似 C#事件) 來簡化這個過程。 以下示例展示了 POCO事件 的用法。 在這個示例中, Source 擁有 一個公有事件,名為 theEvent 它有一個參數,類型為 int 。訂閱 者可以通過調用 operator +=來訂閱,調用 operator -= 來取消訂閱,並且 要傳入兩個參數:指向某個對象 的一個指針;以及,指向某個成員函數 的指針。事件 可通用調用 operator () 來發射, Source::fireEvent() 中就是這麽做的。

#include "Poco/BasicEvent.h"

#include "Poco/Delegate.h"

#include <iostream>

using Poco::BasicEvent;

using Poco::Delegate;

class Source

{

public:

BasicEvent<int> theEvent;

void fireEvent(int n)

{

theEvent(this, n);

}

};

class Target

{

public:

void onEvent(const void* pSender, int& arg)

{

std::cout << "onEvent: " << arg << std::endl;

}

};

int main(int argc, char** argv)

{

Source source;

Target target;

source.theEvent += Delegate<Target, int>(

&target, &Target::onEvent);

source.fireEvent(42);

source.theEvent -= Delegate<Target, int>(

&target, &Target::onEvent);

return 0;

}

POCO 中的那些流式操作類,已經介紹過了。 為了對它們進行增強,還提供了 Poco::BinaryReader Poco::BinaryWriter ,用於從流中讀取及寫入二進制數據,並且會自動、透明地處理字節序問題。

在復雜的多線程程序中,找出問題及缺陷的唯一手段就是輸出詳盡的日誌信息。POCO提供了一個功能強大且可擴展的日誌框架,它支持:過濾;路由到不同的頻道;以及,日誌消息的格式化。日誌信息可被寫入到以下目標:終端;文件;syslog守護進程;或者,發送到網絡。如果POCO 提供的這些頻道還不能滿足妳,那麽,還可以輕易地使用新的類來擴展日誌框架。

對於 在運行時 載入( 及卸載 )共享 庫的任務, POCO提供 了一個低層的 Poco::SharedLibrary 類。 在它之上,是 Poco::ClassLoader 類模板,以及對應的支持框架,使 得妳可以在運行時動態地載入及卸載 C++ 類,這就類似於 Java .NET 中的功能。 類載入器框架,也使得, 妳可以輕易地以平臺無關的方式來 為程序加入插件支持功能。

最後 POCO Foundation 中包含了對於多線程編程的不同層次的抽象。 Poco::Thread 類,以及常用的同步原語 ( Poco::Mutex Poco::ScopedLock Poco::Event Poco::Semaphore Poco::RWLock ) 一個 Poco::ThreadPool 類, 以及對於線程本地存儲的支持, 也有高級的抽象,例如活躍對象(active objects)。簡單 來說,活躍對象,指的就是, 它有某些方法,是在獨立的線程中執行的。 這樣,就可以進行異步 的成員函數調用——調用 一個成員函數, 在它正在執行的過程中, 去幹一些其它的事,最後,獲取 該函數的返回值。下面 的示例中展示了在POCO 中如何做到這一點。 ActiveAdder 類定義了一個活躍方法(active method) add() 該方法是由 addImpl() 這個成員函數來實現的。 main() 中調用該活躍方法,就會產生出一個 Poco::ActiveResult ( 也被稱作未來對象( future ),最終會通過它來獲取到該函數的返回值。

#include "Poco/ActiveMethod.h"

#include "Poco/ActiveResult.h"

#include <utility>

#include <iostream>

using Poco::ActiveMethod;

using Poco::ActiveResult;

class ActiveAdder

{

public:

ActiveAdder(): add(this, &ActiveAdder::addImpl)

{

}

ActiveMethod<int, std::pair<int, int>, ActiveAdder> add;

private:

int addImpl(const std::pair<int, int>& args)

{

return args.first + args.second;

}

};

int main(int argc, char** argv)

{

ActiveAdder adder;

ActiveResult<int> sum = adder.add(std::make_pair(1, 2));

// 做些別的事情

sum.wait();

std::cout << sum.data() << std::endl;

return 0;

}

XML

POCO XML 庫提供了對於XML 的讀取、處理和輸出功能。出於POCO 的某個指導原則方面的考慮——不要嘗試重新發明那些已經有用的東西—— POCO XML 庫支持工業標準的 SAX (版本2) DOM接口 這會令狠多用過XML 開發者 倍感親切。 SAX ,即為XML的簡單API( Simple API for XML ( http://www.saxproject.org ) ),定義 了一個基於事件的接口,用於讀取 XML 基於 SAX XML解析 器,會遍歷整個 XML文檔 ,並且在遇到元素 、字符數據或其它XML 事物時通知應用程序。 SAX解析 器不需要將整個 XML文檔 讀入到內存中,因此 可用來高效地解析巨型XML 文件。 反過來, DOM (文檔對象模型 Document Object Model, http://www.w3.org/DOM/ ) ,使得應用程序能夠以一個樹型風格的對象層次來完整地訪問XML 文檔。 為了完成工作,POCO 提供的 DOM解析 器必須將整個文檔載入到內存中。 為了減少DOM 文檔的內存占用, POCO 中的 DOM實現代碼 用上了字符串池,使得 經常出現的字符串 (例如元素和屬性名字) 只會被存儲一次。 這個 XML 庫基於 Expat開源XML解析 ( http://www.libexpat.org )開發Expat 為基礎的是 SAX接口 ,而以 SAX接口 為基礎的就是 DOM實現 。對於字符串 XML 庫使用的是 std::string ,並且 以 UTF-8 作為字符編碼。 這就使得 XML庫可輕易地與程序中的其它部分配套使用。 在未來的版本中將支持XPath 和XSLT。

Util

Util庫的名字可能會讓妳產生誤解,實際上,它主要是一個用來創建命令行程序和服務器程序的框架。包含的功能:處理命令行參數(驗證、綁定到配置屬性,等等);以及,管理配置信息。支持不同的配置文件格式——Java風格的屬性文件、XML文件

對於服務器程序,這個框架提供了對於Unix 守護進程的透明支持。當然,所有的服務器程序也都可以直接從命令行啟動,這樣便於測試及調試。

Net

POCO的Net庫使得妳能夠輕易地寫出基於網絡通信的應用程序。無論妳只是想使用普通的TCP 套接字來發送數據,還是想要一個內置的完整功能的HTTP 服務器,Net 庫都能滿足妳。

在最底層, Net 庫提供了一些套接字類 ,支持: TCP 流;服務器套接字; UDP 套接字;多播套接字; ICMP ;和原始套接字。如果 妳的程序中需要用到安全的套接字,那麽,請使用 NetSSL 庫,它是利用OpenSSL ( http://www.openssl.org )實現的。 以這些套接字類為基礎,提供了兩個用來構建TCP 服務器的框架—— 一個用來構建多線程服務器 (對於每個連接 都使用一個線程,該線程取自一個線程池 ) ,一個用來構建接收 者-響應者( Acceptor-Reactor 模式的服務器。 多線程的 Poco::Net::TCPServer 類和它的支持框架,同時也是POCO 的HTTP 服務器實現( Poco::Net::HTTPServer )的基礎。 在客戶端開 發方面, Net 庫提供了起到以下作用的類: HTTP服務器通信 ;使用FTP 協議 發送及接收文件;使用SMTP 協議 發送郵件 (包含附件) 從POP3 服務器接收郵件。

將這些東西組合到一起

下面 的示例,展示了利用POCO 庫實現的一個簡單的HTTP 服務器。 這個服務器會返回一個 HTML文檔 ,裏面顯示的是當前日期和時間。 在這裏,用上了應用程序框架, 以開發出一個可以Unix 守護進程的形式運行的服務器程序。當前 這個程序也可以在終端中直接啟動。 在使用HTTP 服務器框架的過程中,定義 TimeRequestHandler 這個類, 它返回一個包含當前日期及時間的HTML 文檔,以對來自客戶端的請求進行響應。 同時,對於所接收到的每個請求, 都會利用日誌框架輸出一條日誌信息。 為了與TimeRequestHandler 類配套使用,還需要一個工廠類 TimeRequestHandlerFactory 該工廠類的一個實例會被傳遞給 HTTP服務器對象 HTTPTimeServer 這個應用程序類,定義了一個名為help 的命令行參數,具 體做法就是覆蓋 Poco::Util::ServerApplication defineOptions() 成員函數。另外 在啟動HTTP 服務器之前, 還會在main() 中(通過 initialize() )讀取默認的程序配置文件,並且取得某些配置屬性的值。

#include "Poco/Net/HTTPServer.h"

#include "Poco/Net/HTTPRequestHandler.h"

#include "Poco/Net/HTTPRequestHandlerFactory.h"

#include "Poco/Net/HTTPServerParams.h"

#include "Poco/Net/HTTPServerRequest.h"

#include "Poco/Net/HTTPServerResponse.h"

#include "Poco/Net/HTTPServerParams.h"

#include "Poco/Net/ServerSocket.h"

#include "Poco/Timestamp.h"

#include "Poco/DateTimeFormatter.h"

#include "Poco/DateTimeFormat.h"

#include "Poco/Exception.h"

#include "Poco/ThreadPool.h"

#include "Poco/Util/ServerApplication.h"

#include "Poco/Util/Option.h"

#include "Poco/Util/OptionSet.h"

#include "Poco/Util/HelpFormatter.h"

#include <iostream>

using Poco::Net::ServerSocket;

using Poco::Net::HTTPRequestHandler;

using Poco::Net::HTTPRequestHandlerFactory;

using Poco::Net::HTTPServer;

using Poco::Net::HTTPServerRequest;

using Poco::Net::HTTPServerResponse;

using Poco::Net::HTTPServerParams;

using Poco::Timestamp;

using Poco::DateTimeFormatter;

using Poco::DateTimeFormat;

using Poco::ThreadPool;

using Poco::Util::ServerApplication;

using Poco::Util::Application;

using Poco::Util::Option;

using Poco::Util::OptionSet;

using Poco::Util::OptionCallback;

using Poco::Util::HelpFormatter;

class TimeRequestHandler: public HTTPRequestHandler

{

public:

TimeRequestHandler(const std::string& format): _format(format)

{

}

void handleRequest(HTTPServerRequest& request,

HTTPServerResponse& response)

{

Application& app = Application::instance();

app.logger().information("Request from "

+ request.clientAddress().toString());

Timestamp now;

std::string dt(DateTimeFormatter::format(now, _format));

response.setChunkedTransferEncoding(true);

response.setContentType("text/html");

std::ostream& ostr = response.send();

ostr << "<html><head><title>HTTPTimeServer powered by "

"POCO C++ Libraries</title>";

ostr << "<meta http-equiv= \" refresh \" content= \" 1 \" ></head>";

ostr << "<body><p style= \" text-align: center; "

"font-size: 48px; \" >";

ostr << dt;

ostr << "</p></body></html>";

}

private:

std::string _format;

};

class TimeRequestHandlerFactory: public HTTPRequestHandlerFactory

{

public:

TimeRequestHandlerFactory(const std::string& format):

_format(format)

{

}

HTTPRequestHandler* createRequestHandler(

const HTTPServerRequest& request)

{

if (request.getURI() == "/")

return new TimeRequestHandler(_format);

else

return 0;

}

private:

std::string _format;

};

class HTTPTimeServer: public Poco::Util::ServerApplication

{

public:

HTTPTimeServer(): _helpRequested(false)

{

}

~HTTPTimeServer()

{

}

protected:

void initialize(Application& self)

{

loadConfiguration();

ServerApplication::initialize(self);

}

void uninitialize()

{

ServerApplication::uninitialize();

}

void defineOptions(OptionSet& options)

{

ServerApplication::defineOptions(options);

options.addOption(

Option("help", "h", "display argument help information")

.required(false)

.repeatable(false)

.callback(OptionCallback<HTTPTimeServer>(

this, &HTTPTimeServer::handleHelp)));

}

void handleHelp(const std::string& name,

const std::string& value)

{

HelpFormatter helpFormatter(options());

helpFormatter.setCommand(commandName());

helpFormatter.setUsage("OPTIONS");

helpFormatter.setHeader(

"A web server that serves the current date and time.");

helpFormatter.format(std::cout);

stopOptionsProcessing();

_helpRequested = true;

}

int main(const std::vector<std::string>& args)

{

if (!_helpRequested)

{

unsigned short port = (unsigned short)

config().getInt("HTTPTimeServer.port", 9980);

std::string format(

config().getString("HTTPTimeServer.format",

DateTimeFormat::SORTABLE_FORMAT));

ServerSocket svs(port);

HTTPServer srv(new TimeRequestHandlerFactory(format),

svs, new HTTPServerParams);

srv.start();

waitForTerminationRequest();

srv.stop();

}

return Application::EXIT_OK;

}

private:

bool _helpRequested;

};

int main(int argc, char** argv)

{

HTTPTimeServer app;

return app.run(argc, argv);

}

http://www.stupidbeauty.com/Blog/article/1648/POCO%E6%96%87%E6%A1%A3%E7%BF%BB%E8%AF%91%EF%BC%9APOCO%20C++%E5%BA%93%E5%85%A5%E9%97%A8%E6%8C%87%E5%8D%97,A%20Guided%20Tour%20Of%20The%20POCO%20C++%20Libraries

POCO文檔翻譯:POCO C++庫入門指南