C++/CLIで作成したDLLが正しくロードされない件について

例えば,

  • Visual C++CLR > クラスライブラリ プロジェクトを, CppCLI という名前で作成します.
  • Visual C# > Windows > コンソールアプリケーション プロジェクトを, CSharp という名前で作成します.


そして,
C++/CLIコード

// CppCLI.h

#pragma once

using namespace System;

namespace CppCLI {

	public ref class Class1
	{
	};
}

他はデフォルトのまま


C#コード

using System;
using System.Collections.Generic;
using System.Text;

namespace CSharp
{
    class Program
    {
        static void Main(string[] args)
        {
            CppCLI.Class1 c = new CppCLI.Class1();
        }
    }
}

Release モードの CppCLI.dll を参照設定します(もしくは,上記2つのプロジェクトを同一ソリューションに所属させ, CSharp に CppCLI プロジェクトを参照するように設定する).


ビルドして, CSharp.exe と CppCLI.dll を別の PC にコピーします.
実行すると,以下のようなメッセージが出るはずです.

ハンドルされていない例外: System.IO.FileLoadException: ファイルまたはアセンブリ 'CppCLI,Version=1.0.2611.1712, Culture=neutral, PublicKeyToken=null'、またはその依存関係の 1 つが読み込めませんでした。このアプリケーションの構成が正しくないため、アプリケーションを開始できませんでした。アプリケーションを再度インストールすることにより問題が解決する場合があります。 (HRESULT からの例外: 0x800736B1)
ファイル名 'CppCLI, Version=1.0.2611.1712, Culture=neutral, PublicKeyToken=null' です。 --->System.Runtime.InteropServices.COMException (0x800736B1): このアプリケーションの構成が正しくないため、アプリケーションを開始できませんでした。アプリケーションを再度インストールすることにより問題が解決する場合があります。 (HRESULT からの例外: 0x800736B1)
場所 CSharp.Program.Main(String[] args)

いろいろ調べてみたところ, CppCLI.dll が依存している VC8.0 CRT 関連の DLL が読み込まれないため,上記のようなエラーが発生しているようです.
このような依存関係にあるアセンブリは,マニフェストファイルに記述されています.

マニフェストファイルの中身

<?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.VC80.CRT' version='8.0.*****.***' processorArchitecture='x86' publicKeyToken='*****************' />
    </dependentAssembly>
  </dependency>
</assembly>


C/C++ プログラムのマニフェスト生成についての理解によれば,VisualC++のリンカは,マニフェストファイルをバイナリに埋め込まないようです.


そこで,Visual Studio でのマニフェスト生成を参考に,埋め込みを試みましたが,マニフェストファイルを埋め込む」設定であるにもかかわらずうまくゆきません.(×_×)
↑正しく埋め込まれます.


こんどは,C/C++ 分離アプリケーションおよび side-by-side アセンブリのトラブルシューティングhttp://msdn2.microsoft.com/ja-jp/library/ms235591(VS.80).aspxhttp://d.hatena.ne.jp/akiramei/20051127/p3を参考に,mt.exeで埋め込もうとしましたが,うまくいきませんでした.(×_×)
↑できます.すみません.こちらをご参照ください→http://d.hatena.ne.jp/KrdLab/20070224/1172290039


しかし,このままでは共有アセンブリが参照されないので,
実行ファイルのところに,
 C:\Program Files\Microsoft Visual Studio 8\VC\redist\x86\Microsoft.VC80.CRT
 (デバッグモードならば,C:\Program Files\Microsoft Visual Studio 8\VC\redist\Debug_NonRedist\x86\Microsoft.VC80.DebugCRT ←Debugモードで配布はしませんけど...)
を,フォルダごとコピーするという処置をとりました.
↑これでも動きますが,こちらも可能です→http://d.hatena.ne.jp/KrdLab/20070224/1172290039

C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\redist.txtより

VC++ ランタイム ファイルを再頒布する際に利用できる以下のフォルダも用意しました。ソフトウェアの使用許諾条件に従って、アプリケーション ローカル フォルダ内の以下のフォルダ (未変更の状態) を、フォルダの名称を変更せずに、サブフォルダとして再頒布できます。また、フォルダに含まれるすべてのファイル (*.dll および *.manifest) を再頒布することもできます。以下に再頒布できるすべてのフォルダを一覧します。

  • 配置例

http://msdn2.microsoft.com/ja-jp/library/ms235285(VS.80).aspx

  • Microsoft Visual C++ 2005 再頒布可能パッケージ (x86)

http://www.microsoft.com/downloads/details.aspx?FamilyID=32bc1bee-a3f9-4c13-9c99-220b62a191ee&DisplayLang=ja

↓なお,Debugモード用のMicrosoft.VC80.DebugCRTは,再配布が禁止されています.
http://msdn2.microsoft.com/ja-jp/library/8kche8ah(VS.80).aspx


うむむ,これで良かったのかなぁ...

【参考】
メモ: C++/CLI

The resource cannot be found.