zlibという超有名なフリーの可逆圧縮ライブラリがあるのですが、今回はMFCアプリケーションにおけるこのライブラリの使い方について書いてみます。
このライブラリがサポートしている圧縮方式はDeflate/Inflate方式と言いまして、RFC1950に定義されています。この方式は実に様々なところで使われておりますが詳細は省略。さらにこのライブラリのライセンスはとても使いやすくなっていて、このライブラリは実に広く使われておりますが詳細は省略。
詳細は省略しておいてとにかくMFCアプリケーションでこのzlibを使いたいと思ったとします。
それでもってzlibをビルドし、作成されたスタティックライブラリ(zlib.lib)とMFCアプリケーションをリンクしてビルドしたとします。
そうすると、以下のような警告を見かけるかと思います。
ひどいときにはエラーまで出ます。
LINK : warning LNK4098: defaultlib 'LIBC' は他のライブラリの使用と競合しています。/NODEFAULTLIB:library を使用してください。
もし何もエラーがなければ問題ありません。もう以下の記事を読む必要はありません。速やかに作業に戻って下さい。
このエラーが出る理由は、zlib.libとMFCアプリケーションのランタイムライブラリが異なるからです。
以下、詳細を説明します。
ランタイムライブラリとは、C++標準ライブラリの実行コードを収めたライブラリです。Visual C++.NET 2003では、このランタイムライブラリが6種類あります。
そんなにたくさんの種類がある理由は良く分かりません。ランタイムライブラリがたくさんあっても、開発者が混乱するだけでメリットは無いように思えます。
ランタイムライブラリを分けないとMFCが実装できなかった、等、何か止むを得ない事情があったのでしょう。
これらのランタイムライブラリは、以下のように使い分けられています。
ライブラリ | MFCの使用 | Debug/Release | コンパイラオプション |
---|---|---|---|
MSVCRT.lib | 共有DLLでMFCを使用 | Release | /MD |
MSVCRTd.lib | 共有DLLでMFCを使用 | Debug | /MDd |
LIBCMT.lib | スタティックライブラリでMFCを使用 | Release | /MT |
LIBCMTd.lib | スタティックライブラリでMFCを使用 | Debug | /MTd |
LIBC.lib | 標準Windowsライブラリを使用 | Release | /ML |
LIBCd.lib | 標準Windowsライブラリを使用 | Debug | /MLd |
MFCを使う場合と使わない場合で異なるランタイムライブラリが使用されることが分かります。
上記警告(LNK4098)が発生した理由は、zlib.libは「標準Windowsライブラリを使用」設定でビルドし、MFCアプリケーションはMFCを使用する設定でビルドしたため、zlib.libとMFCアプリケーションで異なるランタイムライブラリが使用されたからです。
やっとエラーが発生した理由が分かりました。
一番簡単な解決先は、zlib.libのランタイムライブラリをMFCアプリケーションと合わせてしまうことです。
MFCアプリケーションの方はMFCを使う以上変更できないようなので、zlib.libの方を合わせます。プロジェクトの設定からC/C++→コード生成→ランタイムライブラリ の設定を、MFCアプリケーションと同じものにしましょう。これで解決です。
しかし、zlib.libの方を変えてしまうと、非MFCアプリケーションでzlib.libを使うとき同じような問題が発生します。
ではどうすれば良いかと言いますと、こんなのはどうでしょう。
ランタイムライブラリが6種類あるので、夫々のランタイムライブラリ用にzlib.libを6種類作ってしまうのです。スマートな解決方法ではありませんが、一応問題は全て解決です。
6種類のzlib.libを作成するためのVisualC++.NET 2003用のプロジェクトを作りました。zlib 1.2.2用です。他のバージョンで動くかどうかは分かりません。このプロジェクトファイルをzlib.cやzlib.hと同じフォルダに置き、開いて下さい。
開いた後、全構成のバッチビルドを行ってください。libというフォルダが作成され、その中に6つのライブラリファイルができているはずです。
zlibを使いたいときは、使う側の都合に合わせて適切なライブラリをリンクして下さい。