Written in Japanese(Shift-JIS)
2012. 3.10
INASOFT

/トップ/目次/管理人のひとこと(ブログ)/Visual Studio 2010を使い始めてみましたが

2080722 (+0061)[+0371]

管理人のふたこと Tweet

Visual Studio 2010を使い始めてみましたが

〜Visual Studio 2005→2010移行メモ〜



公開日:2012/ 2/11
更新日:2012/ 3/10 バージョン情報について

現在、Visual Studio 2010の試用をしています。
来月から本格的に使用しようと考えているため、今の期間にできるだけノウハウを蓄積していこうと思っているわけですが、メモがてら、どんなトラブルが起きたか書いていこうかと思います。

まず、基本的な話になりますが、Visual C++ 2010 で生成したネイティブなexeは、Windows 95/98/Me/NT4.0/2000 では動作しなくなります。
この点については、過去のWindowsとの互換を重要視されている方には要注意ポイントとなります。

なお、上で「ネイティブなexe」という書き方をしたのは、.NET Framework対応のexeの場合は、また話が変わってくるからです。
.NET Framework対応のexeの場合は、その.NET Frameworkのバージョンに寄ってきます。

例えば、Visual Basic .NET 2010で、.NET Framework 2.0対応のexeを生成した場合は、Windows 2000でも動作します。
もちろん、Windows 2000には、.NET Framework 2.0 をインストールしておく必要がありますが。

さて、ここからは実際に試用してみて出てきた問題点を挙げたいと思います。
とりあえずお試しとして、最近更新頻度の高い「複数行置換(mlrep)」と、複雑性の高い「いじくるつくーる(Rnsf7)」をビルドしてみることにしました。

その1


■複数行置換(mlrep)

こちらは、何の問題も無くソリューションが移行され、ビルドも実行もスムーズに進みました。
ある意味、面白くないですね…。

おそらく、移行元が Visual Basic 6.0 だったら、すごい苦労を伴ったのかもしれませんね。

■いじくるつくーる(Rnsf7)

まずいきなり、下記のようなわけのわからないエラーにぶつかりました。

「構文エラー : ';' が、識別子 'PVOID64' の前に必要です。」

エラーを起こしているのは、winnt.h 内の「typedef void * POINTER_64 PVOID64;」という行です。
Google様でググってみると、多くの方がこの奨励に悩まされており、解決時の方法もいくつかあるそうです。

主な解決策としては、

の2点のようでした。

Visual Studio 2010では、VC++のインクルードディレクトリの設定方法が変更され、また、標準のインクルードと追加のインクルートの取り込み順序も変わったようで、色々とトラブルが起きているようです。
僕の環境では、残念ながら、どのようにインクルード順序を変更しても、うまくエラー回避できませんでした。

なので、winnt.h を改造する方法を取ることにしました。

typedef void * POINTER_64 PVOID64;

 ↓

#ifdef POINTER_64
typedef void * POINTER_64 PVOID64;
#else
typedef void * __ptr64 PVOID64;
#endif

Visual Studio 2008以降、マイクロソフトは32bitコンパイル環境と64bitコンパイル環境のインクルードファイルを統合するために、色々と苦労しているそうなのですが、そのせいで、要らない問題が発生してしまうらしいですね。おそらく後で、POINTER_32 にも問題が起きるんだろうなぁ…。

次は下記のようなエラーがでました。

『オブジェクトまたはライブラリ ファイル 'xxx.lib' は、他のオブジェクトよりも古いコンパイラで作成されました。古いオブジェクトおよびライブラリを再度ビルドしてください。』

xxx.libは、自作ライブラリです。
どうやら、自作ライブラリについても、あらかじめ新バージョンの Visual Studio でコンパイル(というかビルド)せよというお達しのようです。
仕方ないので、すべての自作ライブラリをビルドし直すことにしました。

その2


■環境情報の表示(CCPU)

と、ここで予想通り、「POINTER_32」についても同様のエラー発生となりました。

「構文エラー : ';' が、識別子 'OptionsData' の前に必要です。」

エラーを起こしているのは、ipexport.h の下記の箇所です。

typedef struct ip_option_information32 {
    UCHAR   Ttl;
    UCHAR   Tos;
    UCHAR   Flags;
    UCHAR   OptionsSize;
    UCHAR * POINTER_32 OptionsData;
} IP_OPTION_INFORMATION32, *PIP_OPTION_INFORMATION32;

上記の構造体は、64bitコンパイルの際に流れ、32bit用のポインタを含んだ構造体を提供してくれるわけですが、そこのところで「POINTER_32」が空定義になってしまっていて、問題を起こしている様子。
通常、64bitコンパイル環境では、「POINTER_32」は「__ptr32」になっているはずなのですが……どこかで何かが悪さをしているんでしょうか。

とりあえず、ipexport.h を取り込んでいる iphlpapi.h のインクルードよりも前に、下記のような定義を入れることで問題を解決しました。

#ifdef _WIN64
#define POINTER_32 __ptr32
#endif /*_WIN64*/

新しいインクルードファイルを作るにあたり、マイクロソフトは、ちゃんと十分なデバッグしているんだろうなぁ……。

■汎用ツールライブラリ(toolfunc.h)

次のエラーが発生しました

「'void **IID_PPV_ARGS_Helper(T **)' : 関数テンプレートは既に定義されています」

身に覚えがあるなぁと思い、ソースコードを観てみたところ、次のような記述が存在していました。

// ここから↓ Visual Studio 2005でコンパイルするには定義が不足しているので追加。
extern "C++"
{
    template void** IID_PPV_ARGS_Helper(T** pp) 
    {
        static_cast(*pp);    // make sure everyone derives from IUnknown
        return reinterpret_cast(pp);
    }
}

#define IID_PPV_ARGS(ppType) __uuidof(**(ppType)), IID_PPV_ARGS_Helper(ppType)
// ここまで↑

これは、Windows XPのOS標準機能としてのzip解凍機能を利用しようとしたときに必要となる定義です。
Visual Studio 2010を使用し始めるにあたって、削除しなければならない記述でした。

というわけで、削除(コメントアウト)します。

さて、いよいよ、いじくるつくーる本体のビルド作業に戻ります。

■いじくるつくーる(Rnsf7)【リベンジ】

というわけで、すべての自作ライブラリのビルドが完了しましたので、引き続き、いじくるつくーるのビルド作業に戻ります。
すると、次のようなエラーと遭遇。

「manifest authoring error c1010001: Values of attribute "level" not equal in different manifest snippets.」

英語は嫌です…。

とりあえずググってみると、Visual Studio が標準で準備してくれるマニフェストファイルの「requestedExecutionLevel level」と、自作しているマニフェストファイルの「requestedExecutionLevel level」が異なっている、というエラーのようです。

プロジェクトの構成プロパティの「リンカー」の「マニフェスト ファイル」の中には、「UACの実行レベル」という名前で、標準で準備されるマニフェストに記述するための設定が書き込めるようになっており、たしかに、ここと競合しているようですね。
というわけで、上記設定の「UACの実行レベル」を、自作しているマニフェストファイルの「requestedExecutionLevel level」と合わせるようにして、問題解決です。

【追記】バージョン情報

プログラムリソースのバージョン情報について、これまで「カンマ区切り」だったものが「コロン区切り」に変わっておりました。そのため、プログラムのバージョン情報をリソース(\StringFileInfo\041104b0\FileVersion等)から得て、バージョン情報ダイアログの表示等に利用している場合、カンマ区切りを前提とした作りになっていると、失敗します。

また、SpecialBuild(\StringFileInfo\041104b0\SpecialBuild等)もデフォルトでは存在しなくなっているようなので、これに依存するプログラムを作っている場合は注意が必要です。



本ページへは、自己責任の範囲内であれば自由にリンクしていただいて構いません。
本ページに掲載されている内容は、自由にお使いいただいて構いませんが、必ずしも筆者が内容を保証するものではありませんので、ご利用に際しては自己の責任においてお使いいただきますよう、お願いいたします。
このページのURLやアンカーは、サーバ運営・サイト運営・ページ運営・その他の都合により無告知で一時的あるいは永遠に消滅したり、変更したりする可能性がありますので、あらかじめご了承下さい。
本ページは、公開から1年半経過後の任意のタイミングで削除される予定です。本ページの内容は複製・公開していただいて構いません。


/トップ/目次/管理人のひとこと(ブログ)/Visual Studio 2010を使い始めてみましたが