[ C++で開発 ]

Visual C++ 9.0

コンパイラ特有のプリプロセッサ定義

_MSC_VER

定義シンボル 規定値
_MSC_VER
1500

STL

Visual C++ 9.0 標準搭載STL

Visual C++ 7.1以降のSTLライブラリは、hash_set, hash_mapといった標準C++以外の拡張が含まれています。これらは、stdext名前空間に入ります。

hash_set、hash_multiset

#include <hash_set>
using stdext::hash_set;

hash_map、hash_multimap

#include <hash_map>
using stdext::hash_map;

Boostを使う

VC++ 9.0でBoostを使ってみましょう。

Boostのセットアップ

バイナリ版(1.34.1)

まず、Boost Consultingサイトから、Visual C++用オンライン・インストーラを入手します。

Boostのバイナリ版(オンラインインストーラによるダウンロードとインストール)がVisual C++ 7.1およびVisual C++ 8.0用にリリースされています。これを試してみましょう。まずはインストーラを実行し、コンパイラにVisual C++ 8.0をチェックし、とりあえず最小限でMultithread Debug DLLおよびMultithread DLLを選択してインストールします。

VC++8.0用のBoostバイナリ版を使ってビルドしたときの問題

grergorianの簡単なプログラムを書いてビルドすると、コンパイル時に以下の警告が出ました。

Unknown compiler version - please run the configure tests and report the results
1>d:\lib\boost_1_34_1\boost\lexical_cast.hpp : warning C4819: The file contains a character that cannot
 be represented in the current code page (932). Save the file in Unicode format to prevent data loss

また、リンク時に以下のエラーが発生しました。

1>LINK : fatal error LNK1104: cannot open file 'libboost_date_time-vc80-mt-gd-1_34_1.lib'

libboost_date_time-vc80-mt-gd-1_34_1.libは、スタティック・リンク・ライブラリ版で、今回はインストールしていません。プロジェクト設定でDLLインポートライブラリのboost_date_time-vc80-mt-gd-1_34_1.libおよびそのパスを指定しても、上記エラーは発生します。boostのソースコード等でリンクするライブラリファイルが記述されているように思われます。

Windows版のBoostは、ライブラリのリンクをソースコード(boost/config/auto_link.hpp)で制御しています。VC++の場合は、#pragma comment(lib, "...") を使用しています。以下がその定義箇所(の抜粋)です。

#  pragma comment(lib, BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME)
 "-" BOOST_LIB_TOOLSET BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT "-" BOOST_LIB_VERSION ".lib")

よって、VC++のプロジェクトのリンク設定でいくらDLL用のインポートライブラリ(例、boost_date_time-vc80-mt-gd-1_34_1.lib)を指定しても、それとは違うファイル名のリンクをしに行ってエラーが発生してしまいます。

そこで、このauto_link.hppで意図する(ダイナミックリンク用)ライブラリ名をリンクするようにデファインで制御します。リンクするライブラリ名を静的リンク用か動的リンク用かを制御している箇所が次になります。

#if (defined(_DLL) || defined(_RTLDLL)) && defined(BOOST_DYN_LINK)
#  define BOOST_LIB_PREFIX
#elif defined(BOOST_DYN_LINK)
#  error "Mixing a dll boost library with a static runtime is a really bad idea..."
#else
#  define BOOST_LIB_PREFIX "lib"
#endif

DLLを使用するときは、プリプロセッサ定義で_DLL、または_RTLDLLかつBOOST_DYN_LINKを定義する必要があります。最初、このBOOST_DYN_LINKと_DLLをVC++で定義してビルドしていましたが、boost/config/user.hppにあるデファインBOOST_ALL_DYN_LINKを使用するのが正しい用法と思われます。

// BOOST_ALL_DYN_LINK: Forces all libraries that have separate source, 
// to be linked as dll's rather than static libraries on Microsoft Windows 
// (this macro is used to turn on __declspec(dllimport) modifiers, so that 
// the compiler knows which symbols to look for in a dll rather than in a 
// static library).  Note that there may be some libraries that can only 
// be statically linked (Boost.Test for example) and others which may only 
// be dynamically linked (Boost.Threads for example), in these cases this 
// macro has no effect.
// #define BOOST_ALL_DYN_LINK

boost/config/user.hpp のコメントを解除するか、VC++のプロジェクトにBOOST_ALL_DYN_LINKを定義するか、あるいはソースコード中でboost関連ヘッダーファイルを#includeするより前に#define するかの方法で定義します。

結論

ソース版(1.34.1)

まず、SourceForgeサイトのBoost C++プロジェクト・ダウンロードページから、Boostのソースコードおよびビルドツールboost-jamをダウンロードします。

Boostのソースコードを、ビルド作業用のディレクトリに展開します。

C:\Users\torutk\work\boost_1_34_1

boost-jamに含まれるbjam.exe(バイナリ)を上記ディレクトリに置きます。

Boost 1.34.1は、VC++8.0までの対応です。nmakeコマンドでビルドする分には、VC++8.0の設定で問題ないと思われます。

メモ:bjam用設定ファイルでVC++に関係するファイルと、Boost利用アプリケーションをコンパイルする時に関係するファイルを以下に示します。ここに、9.0用の設定を足してみました。

tools/build/v2/tools/msvc.jam
boost/config/compiler/visual.hpp
boost/config/auto_link.hpp

ビルドを実行します。

C:\Users\torutk\work\boost_1_34_1> bjam --prefix=C:\lib\boost --toolset=msvc-9.0 install
    :
C:\Users\torutk\work\boost_1_34_1> 

--prefixで指定したディレクトリの下に、includeとlibのディレクトリが作成され、それぞれの下にヘッダーファイルとライブラリファイルがインストールされます。UNIXでのインストールを意識したディレクトリ階層になっているため、Windowsではちょっと変則的な気がします。

C:\lib\boost
        +--- include
        |        +--- boost-1_34_1
        |                     +--- boost
        |                            +--- 各ヘッダーファイル、サブディレクトリ
        +--- lib
              +--- 各ライブラリファイル