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


內容目錄

介紹

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= \" \" ></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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM