场景:
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!
.
.
.
.
.
.
本文介绍了一个使用C++实现的示例程序,该程序利用curl库下载XML文件,并采用expat库解析XML内容。为了确保UI响应速度,整个过程在一个独立的工作线程中执行。
3514

被折叠的 条评论
为什么被折叠?



