質問: visual studio 2017 professional を用いてC++の実装をしているのですが、既存のソリューションを読みこんだ際にビルド/リビルドを行ったのですが、構成マネージャをwin32にして行うと、ビルド自体は正常終了するのですが、 ``` 〇〇dllを開始できません。〇〇dllは有効なwin32アプリケーションではありません。 ``` とエラーダイアログが表示されます。そこでx64にしてビルドを行うと、先ほどは出力されなかったエラーで、 ``` 無効な型変換です ``` というエラーが一部指摘され、ビルドに失敗します。 なぜ、win32ではビルドが通ったのに、x64だとビルドが通らないのか、原因と解決策を教えていただきたいです。
回答: `WPARAM` は 32bit 環境では 32bit 値、 64bit 環境では 64bit 値なのに対して `UINT` は両環境で 32bit です。そのためもともと `UINT` を引数にとる関数をキャストで無理やり `WPARAM` を受け取るように変換しても、ポインタを受け渡す目的は達せず、動きません。 ``` int g(UINT w, LONG u) { return 0; } int (*p)(WPARAM, LONG)=g; // C2440 p = static_cast(g); // C2440 // reinterpret_cast しても期待通りに動かないので意味がない。 ``` 当該ソースコードはたぶん x64 が普及する前のもので 64bit 化を意識せずに書かれているのでしょう。その当時のソースコードでは整数型とポインタ型のサイズが同じ前提で書かれているものが多いです(オイラも書いたことがあります)。 Windows の 64bit 版は LLP64 モデルを採用しているので `int` や `UINT` は 32bit サイズ、ポインタは 64bit サイズとなっています。そのため整数型とポインタ型が同じサイズである前提で書かれているコードは要修正となります。 * ポインタをウインドウメッセージでやり取りする際には `INT` でなく `INT_PTR` * `SetWindowLong` でなく `SetWindowLongPtr` を使う などなど。 提示エラーメッセージから推測するに、そのコードで関数の仮引数の型が `UINT` になっているところを `UINT_PTR` に修正すればうまくいきそうに思えます(ソースコード提示がないので妄想レベルですが) ただそこ一か所だけとはとても思えないので、プロジェクト全体を見直す必要がありそうです。プロジェクトのプロパティで「64ビット移植への対応」が「はい」になっている(はずですよね?)なら、その辺の非互換なところで警告が出ますので、ひとつ残らず、すべて対処したら 64bit 化できることと思います。型名を変更するとか、互換な拡張関数に変えるとか、知っていれば単純作業だったりしますが、知らないとなるととても困難ですし、分量がとてつもないことになってしまうかもしれません。 とりあえず 32bit/64bit の移植の経験者なり、知見のある人に見てもらったほうがよさそうです。 DLL を動かすには EXE が必要ですけどその辺はOKっすよね?