C#とマネージC++プロジェクトを含むソリューションがあります。ソリューションプラットフォームx64およびx86でコンパイルされます。 C++で管理されているので、「任意のCPU」ソリューションを作成して、古いソリューションを削除したいと思いました。
C++プロジェクトのリンカー設定をx64とx86の両方でForceSafe ILImageに変更しました。
次に、Configuration Managerを使用して、「AnyCPU」という新しいソリューションプラットフォームを作成しました。次に、「AnyCPU」とも呼ばれるプロジェクトプラットフォームを追加しました。
すべてのC#プロジェクトを「任意のCPU」に設定しましたが、C++の場合はそれができません。プロジェクトプラットフォーム「AnyCPU」はドロップダウンになく、オプション「New ...」もありません。
VSはそれについて熱心に取り組んでいるので、私はそれをそのままにしてビルドを開始しました。驚いたことに、C++のプラットフォームがx64であったとしても、結果DLL(C++プロジェクトから)はMSILでした。x32をコンパイルするときにも同じことが起こり、結果はDLL MSILにあります。
何が得られますか? C++プロジェクトを「任意のCPU」に設定できないのはなぜですか?
私の知る限り、C++/CLIプロジェクト用にVisualStudioで「AnyCPU」プロジェクトタイプを作成することはできません。ただし、canC++/CLIプロジェクト(「Win32」プロジェクトタイプの下)を構成して、ターゲットなしで純粋で安全なMSILとしてコンパイルすることができます。プラットホーム。そうすることで、C++/CLI DLLアセンブリを「AnyCPU」C#プロジェクトで使用できるようになります。つまり、構成マネージャーでの実際の名前ではありませんが、事実上「AnyCPU」になります。
「C/C++」プロジェクト設定の場合:
Safe MSIL Common Language RunTime Support (/clr:safe)
「リンカー」プロジェクト設定:
IJW
またはPURE
に明示的に設定されていないことを確認してくださいノート:
C++機能をC#dllで使用するには、C++プロジェクトでx86バージョンとx64バージョンの両方のdllを生成する必要があります。 AnyCPU設定でコンパイルされたC#dllからx86またはx64dllだけを参照することはできません。
AnyCPUdllをC++ dllで再生するための秘訣は、実行時に、アセンブリがC++ dllをロードできないことを確認してから、AppDomainAssemblyResolveイベントをサブスクライブすることです。アセンブリがdllをロードしようとして失敗した場合、コードには、ロードする必要のあるdllを決定する機会があります。
イベントの購読は次のようになります。
System.AppDomain.CurrentDomain.AssemblyResolve += Resolver;
イベントハンドラは次のようになります。
System.Reflection.Assembly Resolver(object sender, System.ResolveEventArgs args)
{
string Assembly_dll = new AssemblyName(args.Name).Name + ".dll";
string Assembly_directory = "Parent directory of the C++ dlls";
Assembly assembly = null;
if(Environment.Is64BitProcess)
{
Assembly = Assembly.LoadFile(Assembly_directory + @"\x64\" + Assembly_dll);
}
else
{
Assembly = Assembly.LoadFile(Assembly_directory + @"\x86\" + Assembly_dll);
}
return Assembly;
}
AnyCPUdllからC++機能にアクセスする方法を示す簡単なプロジェクトを作成しました。