Huny's Dev Blog

mmeapi.h winmm.lib x64 주의사항

오디오 출력을 위한 WaveOutOpen함수를 사용한 프로젝트를 x64 configuration으로 빌드하여 실행할 때, 실행환경에서 함수 인자 타입 문제로 인해 에러가 발생하는 현상을 해결하는 방법
Hun Jang
Hun JangMar 29, 2024
mmeapi.h winmm.lib x64 주의사항

mmeapi.h는 윈도우즈 멀티미디어를 위해 사용된다.

https://docs.microsoft.com/en-us/windows/win32/api/mmeapi/

waveOutOpen 이라는 함수를 통해서 audio데이터를 출력할 수 있는데, 예제는 아래의 사이트에서 확인할 수 있다.

https://docs.microsoft.com/ko-kr/windows/win32/directshow/audio-streaming-sample-code

이 예제를 64비트(x86_64)환경에서 빌드할 때는 아래와 같이 주의사항이 있으므로 소스를 수정하여 빌드 해야지 오류를 방지할 수 있다.

x86의 경우 waveOutOpen을 사용 시 콜백 합수를 전달할 때 (DWORD)로 캐스팅을 하는데 x86_64에서는 함수 포인트가 64비트가 되므로 문제가 발생한다.

원래의 waveOutOpen의 정의도 (DWORD)가 아닌 (DWORD_PTR)로 되어 있기 때문에 이를 잘 변경하여 아래와 같은 함수 정의를 따라 주어야 한다.

또한 Callback 함수의 정의를 보면 예제는 아래와 같다

하지만 실제로 Callback 정의를 보면 아래와 같다

위를 보면 각 DWORD로 정의된 부분이 DWORD_PTR 인 것을 알 수 있다. 이는 x86에서는 포인터의 크기가 DWORD와 동일(4바이트, unsigned long)하여 문제가 발생하지 않지만 x86_64에서는 포인터의 크기가 8바이트(unsigned __int64)가 되므로 dwUser, dw1, dw2에 포인터를 전달하려고 하는 경우 문제가 발생할 수 있다. 따라서 WaveCallback 함수도 DWORD → DWORD_PTR로 변환해주도록 하자.

waveOutOpen에서 dwCallback의 값을 DWORD로 사용하면 waveOutOpen 순간에 프로세스가 종료(kill)된다. Callback 함수의 DWORD를 DWORD_PTR로 바꾸지 않으면 문제가 생길 수도 있고 생기지 않을 수 있다. 이는 DWORD 크기 내의 값만 전달하는 경우 문제가 발생하지 않을 수 있음을 나타낸다.