Windows SDKを試してみた

Visual C++とクロスプラットフォーム - the technote
↑ 未だにVC6がメインの私としては気になる話題。
自分の興味があるところについてコメントしてみる。

Windowsを含むクロスプラットフォームオープンソースソフトウェアの多くが、なぜかやたらとVisual C++ 6.0を前提としています。5年以上前のIDEを「自由に」使える技術者はそういないでしょう。

いくつかの理由があると思います。

  • 昔から開発者している人が多く、VC6を持っているから。
  • 一つだけ登録するなら.dsp/.dswが最も汎用性があるから。VC6のプロジェクトファイルであればVC6以降の全てのVCで読み込める。
  • 単なる趣味人にとっては開発ツールは高価だから。開発ツールを更新していない人に対する配慮。
  • どうせVC2003や2005もすぐ陳腐化するから。最新版だけに対応するメリットがそれほどない。

ちなみにVC6は「旧バージョンの使用 (ダウングレード)」というように今でも入手可能になっています。

Apache Portable Runtime(APR)には、time_tを再定義した引数を取る関数があり、Subversionはこれを利用しています。なので、新しいVCでは、既存APRをリンクしてSubversionをmakeしなおすと失敗します。ポータブルなのに、ポータブルじゃなかった。(繰り返し)

ポータビリティとバイナリ互換性は別の概念ではないかと。
コンパイラやライブラリが変わると処理系が変わることと等しいので、ビルドし直して動くのであれば許容範囲内かなというところ。また、バイナリI/Fにtime_tを埋め込むのであれば、64bit化されることを見越して最初から64bitにしておくと先見性がある感じですね。
ちなみにWindows的にはtime_tを使わない(でSYSTEMTIMEなどWindows nativeの構造体だけ利用する)ことが2000年問題の解決策のはず。(これはこれで解決になってないが)

この新しいWindows SDKに含まれるライブラリは、どうやら古いPlatform SDKとは異なるもののようです。つまり、同じ名前のlibファイルの中身が違うのです。おそらく、Windows Vista(GDI+以上の何かすごいAPIを持ってたり、CrearTypeフォントが使えたり)を考慮して、もうgdi32.dllを直接インポートするライブラリではなくなったのでしょう。

次のエントリにお書きになっていますが、既存のWin32 APIについてはほとんど変更なさそうです。wxWidgetsではPENUMLOADED_MODULES_CALLBACKの引数でひっかかったくらいです。gdi32.dllからインポートする関数なども同じです。
ただし、Windows SDKの.libファイルはちょっと新しい仕様のようで、VC6ではリンクできないようです。Platform SDKまではVC6でも利用できましたが、ついに終了しました。

GetTextExtentPoint32(デバイスコンテキストの現時点における文字列の幅と高さを知るAPI)が、起きるはずのない失敗を起こします。

これの原因は「wxWidgetsのパッチにフォーカス - the technote」でお書きになっていますが、そもそもなぜWINVERが0x600なのかというとwxWidgetsのwrapwin.hの

    #if !defined(__VISUALC__) || (__VISUALC__ >= 1300)
        #define WINVER 0x0600
    #endif

ここで定義しています。WINVERが0x600ということはVista以降でのみ動作するという指示なわけですが、wxWidgets 2.6.4だとファイルのタイムスタンプが2006/03(Vista発売前)です。つまり最新版でいいやという適当な定義だったのが、実際にVistaが発表されてみたら不都合が出たということでしょう。これはwxWidgetsが悪いです。

構造体のサイズが違うというのはShell APIなどでは前からありました。コードとしてはAPIのエラーについては新構造体のサイズでAPIが失敗したら旧構造体のサイズで試すというのが正しい対処方法だと思われます。
もし下位互換性を維持しつつ最新の機能も利用したいのであれば、バージョン毎に異なる部分だけ切り出して、WINVER=0x400/0x500/0x600というように条件を変えてビルドしたモジュールを持っておき、動作時に判別して適切なものを呼び出すという感じにする必要があるでしょう。MMXへの対応なんかと同じですね。

ちなみにWindows SDK(6.2.6000.0.18)に付属するコンパイラバージョンは14.0.50727.762でした。VC2005相当のようです。