SSブログ

VC++6のDLLでSTLを使う [プログラミング]

大いに今更感満載なのですが、Visual C++ 6 の話です。

Visual C++ 6 に付属のSTLは、微妙に“使えない”代物だったりします。
それが、STLの実装に依るのか、VC++6コンパイラのテンプレート解釈の所為なのかは知りませんが。

その“使えない”理由のひとつに、
std::vector以外のSTLコンテナのインスタンスを、DLLとDLLを使用するexeの間で、共有できない』
というのがあります。

std::listのインスタンスをDLLが公開している関数の引数に渡してみたり、std::mapを返すDLLの関数が返したstd::mapオブジェクトを使ってみたりすると、エラーになります。
変なアドレスを参照したとか、そんな感じの実行時エラーです。

MSDNのどこかに詳しい記事があったはずなのですが、見当たらないので、記憶に頼って書きますが、
STLはテンプレートを使用して書かれていることと、std::vector以外のSTLコンテナは要素にアクセスするのに何らかのstatic変数を使用していることが原因のようです。
何故それが駄目なのかは、自分で考えるか、MSDN内を探ってみて下さい。要は、本来1つしかないstatic変数が2つ出来上がってしまうからなのですが。

MSDNに依ると、解決策は2つ程ありました。

【その1】
STLの使用を諦めて、MFCのコンテナクラス、CMapとかCListを使う。

問題外です。

【その2】
データをやり取りするための、STLコンテナをラップしたクラスを作る。

こんな↓クラスを作れ、と言うことらしいです。

class list2
{
  private:
    std::list<int> n_;
  public:
    void push_back(int v);
    // いろいろ省略
};

void list2::push_back(int v)
{
    n_.push_back(v);
}

ただし、クラスやメソッドにテンプレートを使ってはいけないのと、メソッドはインラインにしてはいけないという制限付き。
暗黙のコンストラクタや暗黙のデストラクタはインラインになるので、上のコードでは省略してますが、コンストラクタとデストラクタもちゃんと書かないといけません。

これで、おおよそ解決なのですが、テンプレートが使えないので、std::list<int>std::list<double>とで、別のラッパクラスを作らなければならないのが鬱陶しい。

そこで(ようやく本題)、ラッパクラスをテンプレート並に簡単に作るためのマクロを作ってみました。

VC++6で、DLLでstd::mapを使うためのマクロを入手する】(lhaで圧縮。3Kbyte)

ヘッダファイルをインクルードして、↓の様に書いておくと、StringMapstd::map<int, std::string>と同じように使えます。もちろん、DLL間でデータを受け渡ししてもOKです。allocatorreverse_iteratorは省略してますが。

~.hファイルに
DECLARE_DLL_STL_MAP(StringMap, int, std::string)

~.cppファイルに
IMPLEMENT_DLL_STL_MAP(StringMap, int, std::string)

とりあえず、std::map用のマクロだけ作ってみましたが、同じ要領で他のコンテナ用のマクロも作れます。


以下、おまけ

この問題(DLL間でSTLコンテナを共有できない)の解決策には、実はもう1つあります。
それは、Visual C++ 7以降を使うこと。

新しいVC++では、ちゃんと対策されているみたいです。


さて、では、何故わざわざVC++6環境でこんなマクロを作らなければならなかったかというと……。

ランタイムプログラムをインストールすることは、まかりならん。

と言われていて、Windows XPに標準でインストール済みなのがVC++6までのランタイムだからなのです。

ランタイムプログラムをインストールしたことで、同じランタイム(でもバージョンが微妙に違う)を使用する他のプログラムの挙動に影響すると困るから。

との理由は分からなくも無いのですが、
それなら、ランタイムDLLは使わずに、スタティックにリンクしたら良いんじゃないかと思わなくも無いですが、そういう発想は無いそうです。

ファイルサイズが大きくなるとか気にしてるのかとも思ったのですが、
ランタイムDLLのマイナーバージョンが開発環境とユーザ環境で違う(サービスパックの有無とか、Windows Updateとかで)と困るとの理由から、ランタイムDLLも一緒に配布しているからなぁ。

[船] 今日の一冊
地獄の始末―真贋控帳 (真贋控帳)

地獄の始末―真贋控帳

  • 作者: 澤田 ふじ子
  • 出版社/メーカー: 徳間書店
  • 発売日: 2001/07
  • メディア: 単行本

タグ:VisualC++
nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。