场景:
1.软件需要更新版本时,通过读取配置好的xml文件获得软件最新的版本信息。
2.因为访问网络可能造成延迟,所以不能阻碍界面操作,所以还得用工作线程进行操作。
3.使用expat库做xml分析,curl库下载xml数据流,两个都是跨平台的库,使用也比较方便。
libcurl: http://curl.haxx.se/
expat: http://expat.sourceforge.net/
pthread: http://sources.redhat.com/pthreads-win32/
1.要分析的xml文件
http://www.w3school.com.cn/example/xmle/note.xml
<?xml version="1.0" encoding="ISO-8859-1"?> <note> <to>George</to> <from>John</from> <heading>Reminder</heading> <body>Don't forget the meeting!</body> </note>
2. test_curl.cpp文件
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <string> #include <iostream> #include "curl/curl.h" #include "expat.h" #include "pthread.h" #include "windows.h" using namespace std; #define XML_FMT_INT_MOD "l" static bool bodyStart = false; static void StartElementHandler(void *userData,const XML_Char *name, const XML_Char **atts) { if(!strcmp("body",name)) { bodyStart = true; } } static void EndElementHandler(void *userData,const XML_Char *name) { if(!strcmp("body",name)) { bodyStart = false; } } static void CharacterDataHandler(void *userData,const XML_Char *s, int len) { if(bodyStart && s) { string str(s,len); cout << "inner Text: " << str << endl; } } class DownloadManger { public: static DownloadManger* GetInstance() { if(!download_manger_) { download_manger_ = new DownloadManger(); } return download_manger_; } ~DownloadManger() { download_manger_ = NULL; curl_global_cleanup(); } typedef size_t (*WriteMemoryCallback)(void *contents, size_t size, size_t nmemb, void *userp); int Process(const char* url,WriteMemoryCallback callback_func,void* userdata) { CURL *curl_handle = curl_easy_init(); curl_easy_setopt(curl_handle, CURLOPT_URL, url); curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, callback_func); curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, userdata); curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "test-agent/1.0"); curl_easy_perform(curl_handle); curl_easy_cleanup(curl_handle); return 0; } private: static DownloadManger* download_manger_; DownloadManger() { curl_global_init(CURL_GLOBAL_ALL); } }; DownloadManger* DownloadManger::download_manger_ = NULL; static size_t DownloadCallback(void *contents, size_t size, size_t nmemb, void *userp) { size_t realsize = size * nmemb; XML_Parser parser = (XML_Parser)userp; if (XML_Parse(parser, (char*) contents, realsize, 0) == XML_STATUS_ERROR) { fprintf(stderr, "%s at line %" XML_FMT_INT_MOD "u \n", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser)); return 0; } return realsize; } XML_Parser CreateExpatParser() { XML_Parser parser = XML_ParserCreate(NULL); XML_SetUserData(parser, NULL); XML_SetElementHandler(parser, &StartElementHandler,&EndElementHandler); { XML_SetCharacterDataHandler(parser,&CharacterDataHandler); } return parser; } void FreeExpatParser(XML_Parser parser) { XML_Parse(parser, (char*) 0, 0, 1); XML_ParserFree(parser); } void * noMutexStartPthread(void * arg) { DWORD id = GetCurrentThreadId(); cout << "current thread id is: " << id << endl; DownloadManger* manager = (DownloadManger*)arg; XML_Parser parser = CreateExpatParser(); manager->Process("http://www.w3school.com.cn/example/xmle/note.xml", &DownloadCallback,parser); FreeExpatParser(parser); } int main(void) { DWORD id = GetCurrentThreadId(); cout << "main thread id is: " << id << endl; DownloadManger* manager = DownloadManger::GetInstance(); pthread_t t1; pthread_create(&t1, NULL, noMutexStartPthread, manager); pthread_detach(t1); pthread_t t2; pthread_create(&t2, NULL, noMutexStartPthread, manager); pthread_detach(t2); int i = 0; while(i < 10) { cout << "." << endl; Sleep(1000); ++i; } delete manager; return 0; }
3.Makefile文件:
CP="cp" test_curl.exe:test_curl.o ${CP} C:/Users/apple/Desktop/curl/curl-7.28.1/lib/.libs/libcurl-4.dll . ${CP} E:/software/Lib/file/xml-expat-2.0.1/win32/release/share/libexpat-1.dll . ${CP} E:/software/Lib/thread/pthreads-w32-2-8-0/win32/release/share/pthreadGC2.dll . g++ -o test_curl.exe test_curl.o -L/E/software/Lib/thread/pthreads-w32-2-8-0/win32/release/share -lpthreadGC2 -LC:/Users/apple/Desktop/curl/curl-7.28.1/lib/.libs -lcurl-4 -LE:/software/Lib/file/xml-expat-2.0.1/win32/release/share -lexpat test_curl.o:test_curl.cpp g++ -I/E/software/Lib/thread/pthreads-w32-2-8-0/win32/release/share/include -IE:/software/Lib/file/xml-expat-2.0.1/win32/release/share/include -IC:/Users/apple/Desktop/curl/curl-7.28.1/include -c test_curl.cpp -o test_curl.o
4.运行结果:
main thread id is: 8004 current thread id is: 4856 . current thread id is: 6988 inner Text: Don't forget the meeting! . . . inner Text: Don't forget the meeting! . . . . . .