2014/03/18

VC++でxmlを扱おう - libxml2の紹介

C++でXmlを使う必要がある場合、VC++を使うWindows系の開発なら普通はmsxmlでやるだろう。そのためにはComとかBSTRとかちょっと変わった知識が要ると思う。
しかしなにもmsxml一択という訳ではない。そこでC++で使えるmsxml以外のxmlを扱うライブラリの説明をする。

その名は「libxml2」。これはGnomeのXMLライブラリだ。
あまり難しいことは無いがlibxml2のビルド方法、利用方法を纏めておく。 

ライセンスについて

MITライセンスなのでどこかにライセンステキストを載せておけば組み込んで使っても良いらしい。しかしUTF-8以外のエンコードのxml解析のためにiconvを使うのだが、iconvはLGPLということで商用には向かない。もっと緩いライセンスのICUライブラリを使うことも出来るらしい。つまりlibxml2とicuの組み合わせなら商用に使っても多分大丈夫、ということでlibxml2とICUの組み合わせで使う方法を説明する。
(ICUライセンス、というのがちょっと分からないが緩いライセンスというのは確か)(この辺専門家ではないので責任取りません)(ライセンスに堅苦しい文章で「これを使ったことで生じた損害は補償しない」と書くのは必須なんだろうか。GitHubにそんなこと書いてないただのサンプルコードを載せてるけどどこかで損害が出た場合訴えられたりするんだろうか。まさかね・・)。

まずlibxml2

http://xmlsoft.org/downloads.html
とそのダウンロードサイト
ftp://xmlsoft.org/libxml2/
(ちになみにhttps://git.gnome.org/browse/libxml2/ からもダウンロードでき、こちらはZipファイルもある。しかしxmlversion.hがmakeされて無かったので使えなかった。)
イメージはtar.gzなので解凍できるソフトが必要だ。

ダウンロードし、解凍したフォルダ「libxml2-2.9.1\win32\VC10」内にある「libxml2.sln」を開く。VC10、つまりVC2010で作られているようだが2013Expressでも大丈夫なはずだ。
プロジェクトを開くと「libxml2」「runsuite」「iconv(使用不可)」となっている。iconvは空になっている。ICUを使うつもりなので削除しよう。(共通プロパティの参照プロジェクトにiconvがあれば削除しよう)
(また、出力フォルダの設定が独自な感じなのでいつも通りの既定のものに変えてしまってもいい。)この時点ではビルドは出来ない。

とりあえずそのままにしておいて次はICU Libraryを入手しよう。

ICU

http://site.icu-project.org/
ダウンロードサイト(これは現時点の最新だが、もっと新しいのが無いかチェックしよう)
http://site.icu-project.org/download/52
ICUはWindows用にビルド済みのバイナリで配布されている。x86用とx64用があって必要な方だけで良いが、個人的に両方欲しいので両方ダウンロードする。
そして解凍すると両方とも「icu」というフォルダになる。しかしx86の中は「lib」と「bin」、x64の中は「libx64」と「binx64」というようにちゃんとモジュールのフォルダ名が分かれているので、x86とx64を同じ「icu」フォルダにマージしても問題が無い。

今回はこの「icu」と「libxml2」の2つのフォルダを並べて配置
 ├ icu
 └ libxml2-2.9.1
という感じにした。

ビルドのための設定

libxml2プロジェクトのインクルードディレクトリの「libiconv-**(iconvを参照しているパス)」を削除し、代わりに「icu\include」を追加する。上記の配置だと「$(ProjectDir)..\..\..\icu\include」となる。

xmlversion.hがiconvを使う設定になっているので、ICUを使う設定に変更する。
「libxml.h」を開き、「#include <libxml/xmlversion.h>」を右クリックし、xmlversion.hを開く。「iconv」で検索し、
#define LIBXML_ICONV_ENABLED
の上の「#IF 1」を「#IF 0」へ変更、
#define LIBXML_ICU_ENABLED
の上の「#IF 0」を「#IF 1」に変更する。
これで「libxml2」がビルドできるようになるはずだ。


ビルドできるはずなのだが、nanoftp.cでエラーになった。 nanoftp.c と nanohttp.c に以下のディファインを書くとエラーは無くなるのだが・・なんか環境の問題かも
#define SEND_ARG2_CAST
#define GETHOSTBYNAME_ARG_CAST

libxml2.libを使う「runsuite」プロジェクトのビルドにはICUのヘッダファイルとlibファイル、と当然libxml2.lib、あとlibxml2のヘッダファイルが必要。
インクルードディレクトリはlibxml2と同様に「libiconv」のパスを削除し、代わりに「$(ProjectDir)..\..\..\icu\include」を設定する。
そして「リンカー ・ 入力 ・ 追加の依存ファイル」に「$(ProjectDir)..\..\..\icu\lib\icuuc.lib」を追加する(x86の場合)。ICUのlibファイルは色々あるがビルドするにはこれひとつで出来た。これでrunsuiteもビルド出来るはず(libxml2が参照プロジェクトになっているのでlibxml2.libの入力は書かなくても良い)。

さて実行時はビルドして出来たEXEの他にICUのDLLが必要になる。
ICUのbinフォルダにDLLもいろいろあるが、「icudt52.dll」「icuuc52.dll」の2つをexeと同じフォルダに置くと良いだろう。
libxml2を使うサンプルコードはrunsuiteのコードにあるはず(テスト用のコードになっててなんかすごい分かりずらいけど)。

これが出来れば自分のプロジェクトにlibxml2.libとicuのlibファイルを組み込んで作るのも同じだ。

0 件のコメント:

コメントを投稿