フォームをリソースエディタで開こうとするとエラーになる (C++/CLI)

ヘッダファイルをダブルクリックしてリソースエディタで開こうとするとエラーになる。

これはヘッダーファイルの最初のクラスが当該フォームでないため。以下のソースのように前方参照(ref class)を使っていてもうまく動かない。

前方参照を別ファイルに分離

これを回避するには前方参照の部分だけのヘッダーをつくり、それをインクルードすればよい。

前方参照だけのヘッダーheaderref.h

もとのヘッダー

C++/CLIでWndProcを継承実装する

FormでWndProcを宣言する

実装する

ビルドするには/clrオプションを設定しなければならない。

実例ファイル

AnyCPUのアセンブリから自動でx86かx64のアセンブリをロードする

普通にC#でアプリケーションを作るとAnyCPUのアセンブリができる。これは64ビット環境では64ビットで動作し、32ビットの場合は32ビットで動作する。

C++やC++/CLIで作ったライブラリはAnyCPUにすることができない。そしてWindowsでは64ビットアプリは64ビットのライブラリしかロードできない。32ビットも同じ。

AnyCPUのアプリをつくるときにこの問題をどう解決するかのはなし。ここではC++/CLIでライブラリをつくり、それをC#から利用することを考える。

C++/CLIで32ビットと64ビットのライブラリをつくる

作り方は省略。MyLib.x86.dllとMyLib.x64.dllができたとする。

C#でMyLib.x86.dllを参照する

参照するときに、プロジェクトの参照をするのではなく、ファイルを直接参照する。参照のプロパティのCopy LocalをFalseにする。こうすることでビルド時にライブラリがコピーされない。

C#のビルドイベントでMyLib.*をターゲットディレクトリにコピーする

この時のコピー先のパスはランタイムが自動で見つけられない場所にする。自動で見つけると違うdllをロードして例外が発生する。

以下はビルド後のコマンドの例、アプリのフォルダ配下のplatformにコピーしている。

この状態でアプリを起動してもライブラリが見つからない、のエラーが出る。

staticコンストラクタでカスタムローダを設定する

staticコンストラクタはstatic main()よりも早く動く。ここでライブラリが見つからないときのイベントハンドラを設定し、ハンドラで適切なライブラリを読み込む。以下はC#でデフォルトでできるクラスProgramに記述する例。

もともとx86の方を参照しているので、ランタイムはこのファイルがないと通知してくる。ここで環境(Environment.Is64BitProcess)に合わせてライブラリを読み込む。

参照

Using Side-by-Side assemblies to load the x64 or x32 version of a DLL