【C#⇔C++/CLI】ファイルまたはアセンブリ、またはその依存関係の1つが読めませんでした。【トラブルシューティング】


# 概要

Windows専用のアプリケーションなんて今更・・・という昨今ですが、

未だに.NET Frameworkや.NET Coreで、C++のコードとC#のコードをまとめて使うときにC++/CLIというMicrosoftが開発した中間言語を使って、ネイティブコードを共存させたいという需要が狭い世界で存在します。

C++/CLIは、現状C++用のラッパーとしてDLLとして作成する場合での運用でのみ、Microsoftからも推奨されています。

そして、.NET FrameworkのC++/CLIの設定を誤ると、表題のエラーを見かけるようになります。

この狭い世界で何度か開発することがあったので、C++/CLI導入時のチェックリストみたいなのを用意しておこうと思います。

# Windows Forms, WPF, UWPの場合

C++/CLIで結合されているオブジェクトを参照すると、こんな感じのエラーが出てきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281173/c6c3d61f-c8c3-9d53-4415-d01e0361e276.png)

## チェックするべき項目

### 実行ファイル側が"Any CPU"になっていないこと
### 実行されるDLLと実行ファイル側が"x86/Win32"または"x64"に統一されていること

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281173/783b3bca-c263-5e58-bef1-12f42c22fba5.png)

基本的に、C++/CLIで作成されたDLLは、32bitで使用するか64bitで使用するかを指定する必要があります。
両方のCPUで使えるような器用な仕様にはなっていません。
従って、上のように"Any CPU"という設定が混在している場合は、"x86/Win32"または"x64"に設定を統一しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281173/38d3da22-1542-0c91-064e-4fe9d874e312.png)

### 実行予定のDLLが、全く同じディレクトリに含まれていること

① C++/CLI以外に、C++ネイティブDLLが混在する場合は、**ビルド時に自動的に実行ファイルのディレクトリ下に保存してくれません。**
その場合は、ビルドイベントを使って、dllファイル、pdbファイルをコピーするようにしましょう。
(**pdbファイルを入れ忘れると、ネイティブコードのデバッグが出来なくなるので注意すること。**)

② もし依存関係が分からない場合は、Dependenciesをダウンロードして調べると、一目で理解できます。

https://github.com/lucasg/Dependencies


# ASP .NETの場合

ローカルサーバを立てた場合のデバッガの挙動
大体こんな感じの画面になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281173/8c6e66df-5635-945f-9904-e71e2cd43734.png)

## チェックするべき項目

基本的には、上記のケースと同じですが、これ以外に下記の内容も確認しましょう。

### IIS Expressが32ビット版、64ビット版に統一されているかを確認する

ツール>オプション>プロジェクトおよびソリューションを参照

64bitのC++/CLIのDLLを使用する場合は、**Webサイトおよびプロジェクト用IIS Expressの64ビットバージョンを使用する**にチェックを入れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281173/b6704237-e4ff-0fe2-897d-5a8a05ab209e.png)


# その他確認が必要なこと(共通)

## x64で使う場合、x86(Win32)においても、ビルドが実行出来ることを確認する。

**Microsoftの仕様にレガシーコードが多いために発生している問題です！**
2つほど、ご紹介します。

### x64で使用する場合、WinForms/WPF/UWPで定義されているユーザーコントロールは、ビューワーを使うとバグります。

ユーザーコントロール作成(WinForms)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281173/5e9d09ec-0a33-6242-5d69-b24ec5d1941a.png)

↓

デザイナー(WinForms) x86 or Any CPU

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281173/ed294ec1-856e-2ebc-2254-143716176b3b.png)

↓

デザイナー(WinForms) x64
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281173/41d92096-fae4-f94a-8376-d1b6c147bd73.png)

したがって、ユーザーコントロールを使う場合、AnyCPU/Win32で画面を調整した後に、x64で仕様修正・デバッグをするという謎状態になります。
この原因は、.NET Frameworkが32bit版でしかコンパイルされていないことが理由です。

_.NET Core 5/6では修正が入っているかもしれません。現在まだ確認できていません（※筆者）。_


### x64で使用する場合、ASP.NET MVCでCode FirstによるDB Migrationを使用する際は、Win32/x86でも動くことを確認する必要があります。

Code FirstでDB Migrationを使ってデータベースを立ち上げるときに発生した課題です。
x86環境下で動いていることが確認できない場合、Migration操作を行うとエラーが発生します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281173/d96ae555-3ebd-4c17-7992-d33727c2397e.png)

ASP.NETをサポートしているライブラリ群の一部は、これ以外でも、x64ビルドで使えることを公言しておきながら、ビルドではx86(Win32)を要求してくる場合があります。もし、CLIのライブラリの原因追求で問題が発生した場合は参考にしてください。

**※参考サイト**

https://developerhandbook.com/entity-framework/project-failed-to-build-error-when-adding-an-entity-framework-migration-add-migration/