トップページ
ひらく | たたむ | ページトップ
↓マウスで反転選択した文字を検索
VisualStudio
   
ページ内検索 ページ外検索
検索したい文字を入力して
ENTERを押すと移動します。
\n
[ トップページ ]
[ ____CommandPrompt ] [ ____JScript ] [ ____MySQL ] [ ____Cygwin ] [ ____Java ] [ ____Emacs ] [ ____Make ] [ ____Perl ] [ ____Python ] [ ____OpenGL ] [ ____C# ] [ ____StyleSheet ] [ ____C++ ] [ ____Winsock ] [ ____Thread ] [ ____VisualStudio ] [ ____C ] [ ____Win32API ] [ ____Lua ] [ ____PhotoShop ]
ヘッダ検索
___

■ マニフェスト(manifest)

  


    manifest とは
    辞書をひくと "明示する" とある。

    何かというと動的にリンクする Cランタイムの DLL のパスを明示的に指定すること。
    
    今までは PATH がとおったところから順に読んでいた。
    しかし何かをインストールするたびに 異なるバージョンの DLL が上書きされて問題をおこす。

    そこでバージョンも含めて完全なパスを指名してやれ。 という発想になった。


    明示するには
     "実行ファイル名.manifest" という名前で実行ファイルと同じフォルダに置く
     リソースとして実行ファイルに埋め込む
manifest ファイルを生成するには、DLL 版 Cランタイムを指定してコンパイルする。
    cl /MD main.cpp
    link main.obj

    main.exe.manifest が生成される
main.exe 内部にないため, manifest の名前(パス)を変えると実行時に dll を見つけることができなくなる main.exe と同じ名前で同じ Directory に置くこと なお exe 内には どの DLL を利用するかは記述されている
    コンピュータに MSVCR90.dll がないため、プログラムを開始できません。
    コンピュータに MSVCP90.dll がないため、プログラムを開始できません。
    // strings でチェックできる
    strings  foo.exe  | grep "dll"
VisualStudio は デフォルトでは ランタイムライブラリ をスタティックリンクしない そのためランタイムが導入されていない環境では実行時エラーとなる POINT 以下のエラーは 実行ファイル( その manifest ファイルが指している )Runtime が見つかりません。 という意味
    // 以下を意図的に変更すると再現できる
    < dependentAssembly>
      < assemblyIdentity type='win32' name='Microsoft.VC90.CRT' 
          version='9.0.21022.8' processorArchitecture='x86' publicKeyToken='1fc8b3b9a1e18e3b' />
XP このアプリケーションの構成が正しくないため アプリケーションを開始できませんでした アプリケーションを再度インストールすることにより問題が解決する場合があります Vista このアプリケーションのサイド バイ サイド構成が正しくないため アプリケーションを開始できませんでした 詳細については アプリケーションのイベント ログを参照してください このエラーを解決するためには クライアントにランタイムを配布する必要がある
    Visual C++ 2005 再頒布可能パッケージ (x86) 
ご丁寧に次のようにかいてある
  Microsoft Visual C++ 2005 SP1 再頒布可能パッケージ (x86) は
  Visual C++ で開発されたアプリケーションを
  Visual C++ 2005 がインストールされていないコンピュータ上で実行するために必要な
  Visual C++ ライブラリのランタイム コンポーネントをインストールします
POINT ファイルサイズは増えるスタティックリンクしておいたほうが混乱は少ない POINT 最大の問題
    「共有ライブラリに対し互換性を失うような変更が行われた場合にライブラリを呼び出すプログラム側がそれを区別することができない」
    特にOS本体に同梱されるライブラリにおいてこのような変更が行われるとその影響範囲は広範囲になる
ソフトウェアのインストーラがシステムの共有ライブラリのバージョンチェックを行わず古いバージョンに置換してしまうことでも発生する DLL 地獄とは ダイナミックリンクライブラリ (DLL)や Component Object Model (COM)コンポーネントなどのバージョンアップによって 以前のバージョンのDLL・COMコンポーネント等に依存して動作するアプリケーションが動作しなくなる現象のこと 最近ではシステム保護機能や「サイドバイサイド(Side-by-Side, SxS)」と呼ばれる仕組みにより減ってきているが 全面解決には至っていない また Linuxにおいて対象ディストリビューションが異なるパッケージを使用したり サードパーティのパッケージ管理システムやレポジトリを使用することによりライブラリの依存関係が壊れ 同様の事象が発生することが多い
___

■ manifest.ファイルを組み込む

EXeと同じフォルダに、manifestファイルを置くだけ 例えば test.exe があるとすれば、test.exe.manifest を置く UTF-8形式のテキストファイルでなければならない、という点に注意 .manifestファイルの内容は次のとおり 外観を変えるだけならこれだけで良い resource に manifest を組み込む
   < ?xml version="1.0" encoding="UTF-8" standalone="yes"?>
   < assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
       < dependency>
           < dependentAssembly>
               < assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" 
               processorArchitecture="x86" publicKeyToken="6595b64144ccf1df" language="*">
               < /assemblyIdentity>
           < /dependentAssembly>
       < /dependency>
   < /assembly>
あらかじめ用意した .manifest ファイルをリソースに埋め込む 上記で用意したファイルを test.manifestとするなら 例えば次のようにリソースファイルに追加する 追加する場所は 手動で編集するということで .rc2 ファイル内が良い // Editor RT_MANIFEST "res\test.manifest" 0. DLL の version(日付け) が異なるだけで動作しなくなった 特定のプロジェクトのマニフェスト ファイルの生成するには
   [リンカ] > [マニフェスト ファイル]  > [マニフェストの生成] 
新しいプロジェクトは デフォルトでマニフェストファイルを生成する ただし プロジェクトのマニフェストの生成プロパティを使用して プロジェクトのマニフェストの生成を無効にできます このプロパティを [はい] に設定すると このプロジェクトのマニフェストが生成されます それ以外の場合 リンカは アプリケーション コードの依存関係を解決するときにアセンブリ情報を無視し マニフェストを生成しません Visual Studio のビルド システムでは マニフェストを最終的なバイナリ アプリケーション ファイルに埋め込むか 外部ファイルとして生成できる [プロジェクトのプロパティ] > [埋め込みマニフェスト] > [マニフェスト ツール] > [入力と出力] マニフェストは 埋め込まれない場合は外部ファイルとして生成 最終的なバイナリと同じディレクトリに保存される マニフェストが埋め込まれる場合 ソース コードがオブジェクト ファイルにコンパイルされた後 リンカが依存アセンブリ情報を収集する 最終的なバイナリをリンクするときに 後で最終的なマニフェストを生成する際に使用される中間マニフェストが生成される 中間マニフェストの作成とリンクが終了した後 マニフェスト ツールが実行され 最終的なマニフェストがマージされて外部ファイルとして保存される プロジェクト ビルド システムは 次に マニフェストツールによって生成されたマニフェストが バイナリに既に埋め込まれているマニフェストと異なる情報を含んでいるかどうかを検出する バイナリに埋め込まれているマニフェストがマニフェスト ツールによって生成されたマニフェストと異なるとき またはバイナリに埋め込みマニフェストがない場合 Visual Studio は もう一度リンカを呼び出し 外部マニフェスト ファイルをバイナリ内にリソースとして埋め込みます バイナリに埋め込まれているマニフェストが マニフェスト ツールで生成されたマニフェストと同じ場合 ビルドは次のビルド手順に進みます マニフェストは 最終的なバイナリ内にテキストリソースとして埋め込まれます 表示するには 最終的なバイナリを Visual Studio でファイルとして開く マニフェストが確実に正しいライブラリをポイントするようにするには C/C++ プログラムのマニフェスト生成についての理解 manifest は XML ドキュメント POINT exe に組み込むということ ( 本質は 文字列と同じ ) isolated application のマニフェスト アプリケーションが実行時にバインドする共有 side-by-side アセンブリの名前およびバージョンの管理に使用されます side-by-side assemblyのマニフェスト そのアセンブリの名前 バージョン リソース および他のアセンブリへの依存関係を指定します つくりかた アセンブリの作成者が 規則および名前付けの要件に従って手動でマニフェスト ファイルを作成できる また プログラムが CRT MFC ATL などの Visual C++ アセンブリのみに依存する場合は リンカによってマニフェストを自動的に生成できます Visual C++ ライブラリのヘッダーにはアセンブリ情報が含まれているため ライブラリがアプリケーション コードにインクルードされると このアセンブリ情報は リンカによって最終的なバイナリのマニフェストが形成される際に使用されます リンカは マニフェスト ファイルをバイナリに埋め込まない 常に外部ファイルとしてマニフェストを生成する マニフェストが外部ファイルであることは すべてのシナリオにとって適しているとは限りません たとえば プライベート アセンブリでは 埋め込みマニフェストを使用することが推奨されます
















NINJAIDX 15