yambowmerrow
@yambowmerrow

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

C++でのwaveInOut系における引数の型エラー

Q&A

Closed

発生しているエラー

GCCでコンパイルすると以下のようなエラーが吐かれます。

error: cast from 'HWND' {aka 'HWND__*'} to 'DWORD' {aka 'long unsigned int'} loses precision [-fpermissive]
waveInOpen(&hWaveIn,inDevNum,&wfe,(DWORD)hwnd,0,CALLBACK_WINDOW);
                     ^~~~~~~~~~~

言ってることはわかるんですがどうしてなのか……
前後しますが問題のコードはこちらです。

LRESULT CALLBACK WndProc(HWND hwnd , UINT msg , WPARAM wp , LPARAM lp) {
            //割愛
            //waveInOpen関数の第二引数はコンボボックスでセレクトされた値が入ります。
            if(waveInOpen(&hWaveIn,inDevNum,&wfe,(DWORD)hwnd,0,CALLBACK_WINDOW)==MMSYSERR_NOERROR){
                waveInPrepareHeader(hWaveIn,&whdr,sizeof(whdr));
                waveInReset(hWaveIn);
                waveInAddBuffer(hWaveIn,&whdr,sizeof(whdr));
                waveInStart(hWaveIn);
            }
            //割愛
}

ウィンドウプロシージャで、入力された値の入力デバイスを選択して開く、という感じです。
waveInOpen関数の第四引数の型変換が出来てないということなんでしょうけれど、どうも調べる限りどのサイトもこの書き方をしており、どこが違うのかがわからず困っています。
書き間違いか、あるいはGCCの問題なのか……。
根本的な間違いをしている可能性もあり、どこをどう調べればいいのかもよくわかっていない感じです。
何卒皆様のお知恵を拝借できればと思います。よろしくお願いします。

0

1Answer

昔はそれが正しいやり方でした。 仕様は変更されることもあるのであまり古い資料を元にするのはお勧めできません。 一次資料を見れば何が問題なのかは明らかです。

問題はポインタのサイズが違うことです。 32 ビット版の Windows ではポインタは 32 ビットなので DWORD として扱っても問題ありませんでしたが 64 ビット版の Windows ではポインタが 64 ビットなので DWORD にすると精度が失われ (loses precision) ます。 故に 64 ビット版の Windows ではその箇所は 64 ビットの幅の API となっています。

32 ビット版と 64 ビット版では API が違うのです。

waveInOpen の公式ドキュメントによれば現在は四番目の引数の型は DWORD_PTR となっており、これは 32 ビット版と 64 ビット版で自動的に切り替わるものであると説明されています。

1Like

Comments

  1. @yambowmerrow

    Questioner

    なるほど……その点は全く考えられていませんでした。ありがとうございます。
    公式ドキュメントの説明はいささか読みづらく敬遠しがちだったのですが、しっかりと読むようにします。

Your answer might help someone💌