

visual studio 2017 professional
を用いてC++の実装をしているのですが、既存のソリューションを読みこんだ際にビルド/リビルドを行ったのですが、構成マネージャをwin32にして行うと、ビルド自体は正常終了するのですが、

[code]

    〇〇dllを開始できません。〇〇dllは有効なwin32アプリケーションではありません。
    
[/code]

とエラーダイアログが表示されます。そこでx64にしてビルドを行うと、先ほどは出力されなかったエラーで、

[code]

    無効な型変換です
    
[/code]

というエラーが一部指摘され、ビルドに失敗します。

なぜ、win32ではビルドが通ったのに、x64だとビルドが通らないのか、原因と解決策を教えていただきたいです。


CC BY-SA 4.0
2018-10-01T01:02:43.047
48860
2018-10-01T07:20:10.967
2018-10-01T01:32:13.170
3060
30303
question
c++
visual studioでのビルドエラーwin32とx64


`WPARAM` は 32bit 環境では 32bit 値、 64bit 環境では 64bit 値なのに対して `UINT` は両環境で 32bit
です。そのためもともと `UINT` を引数にとる関数をキャストで無理やり `WPARAM`
を受け取るように変換しても、ポインタを受け渡す目的は達せず、動きません。

[code]

    int g(UINT w, LONG u) { return 0; }
    int (*p)(WPARAM, LONG)=g; // C2440
    p = static_cast<int(*)(WPARAM,LONG)>(g); // C2440
    // reinterpret_cast しても期待通りに動かないので意味がない。
    
[/code]

当該ソースコードはたぶん x64 が普及する前のもので 64bit
化を意識せずに書かれているのでしょう。その当時のソースコードでは整数型とポインタ型のサイズが同じ前提で書かれているものが多いです（オイラも書いたことがあります）。

<https://www.wdic.org/w/TECH/LLP64>  
Windows の 64bit 版は LLP64 モデルを採用しているので `int` や `UINT` は 32bit サイズ、ポインタは 64bit
サイズとなっています。そのため整数型とポインタ型が同じサイズである前提で書かれているコードは要修正となります。

  * ポインタをウインドウメッセージでやり取りする際には `INT` でなく `INT_PTR`
  * `SetWindowLong` でなく `SetWindowLongPtr` を使う

などなど。

提示エラーメッセージから推測するに、そのコードで関数の仮引数の型が `UINT` になっているところを `UINT_PTR`
に修正すればうまくいきそうに思えます（ソースコード提示がないので妄想レベルですが）

ただそこ一か所だけとはとても思えないので、プロジェクト全体を見直す必要がありそうです。プロジェクトのプロパティで「６４ビット移植への対応」が「はい」になっている（はずですよね？）なら、その辺の非互換なところで警告が出ますので、ひとつ残らず、すべて対処したら
64bit
化できることと思います。型名を変更するとか、互換な拡張関数に変えるとか、知っていれば単純作業だったりしますが、知らないとなるととても困難ですし、分量がとてつもないことになってしまうかもしれません。

とりあえず 32bit/64bit の移植の経験者なり、知見のある人に見てもらったほうがよさそうです。

DLL を動かすには EXE が必要ですけどその辺はOKっすよね？


CC BY-SA 4.0
2018-10-01T07:20:10.967
48865
2018-10-01T07:20:10.967
8589
48860
answer