在QB64中如何正确声明winmm库的waveInOpen函数?
错误原因
你拿到的返回值2是Windows多媒体API定义的MMSYSERR_BADDEVICEID,触发这个错误除了可能设备ID无效之外,核心问题出在你的函数声明和参数传递规则不符合Win32 API的要求:
- 参数类型宽度完全错误:Win32 API中所有的句柄、指针、
UINT/DWORD类型都是32位宽度,对应QB64中的LONG类型。你把所有参数都声明为INTEGER(QB64中INTEGER是16位有符号整数),参数传递时发生内存截断,API无法正确读取传入的设备ID、结构体指针等值。 - 结构体传递规则错误:
waveInOpen的lpFormat参数要求传入WAVEFORMAT结构体的内存指针,你当前的声明方式会导致QB64按值传递结构体,直接把整个结构体内容压栈,不符合API要求的传指针逻辑。 - 代码笔误:你定义的结构体变量名为
InwaveFormat,但赋值时用的是未定义的waveFormat变量,最终传给API的结构体全是初始0值,也会触发参数校验失败。
正确声明及可运行代码
TYPE WAVEFORMAT wFormatTag AS INTEGER nChannels AS INTEGER nSamplesPerSec AS LONG nAvgBytesPerSec AS LONG nBlockAlign AS INTEGER wBitsPerSample AS INTEGER cbSize AS INTEGER END TYPE DECLARE DYNAMIC LIBRARY "WINMM" FUNCTION waveInOpen& ALIAS "waveInOpen" (ByVal lphWaveIn AS LONG, ByVal uDeviceID AS LONG, ByVal lpFormat AS LONG, ByVal dwCallback AS LONG, ByVal dwInstance AS LONG, ByVal dwFlags AS LONG) END DECLARE CONST WAVE_FORMAT_PCM = 1 CONST CALLBACK_NULL = 0 DIM DevHandle AS LONG DIM DevHandleID AS LONG DevHandleID = 0 ' 用0表示默认音频输入设备,避免设备ID无效问题 DIM InwaveFormat AS WAVEFORMAT InwaveFormat.wFormatTag = WAVE_FORMAT_PCM InwaveFormat.nChannels = 2 InwaveFormat.nSamplesPerSec = 44100 InwaveFormat.nAvgBytesPerSec = 44100 * 4 InwaveFormat.nBlockAlign = 4 InwaveFormat.wBitsPerSample = 16 InwaveFormat.cbSize = 0 c& = waveInOpen(VARPTR(DevHandle), DevHandleID, VARPTR(InwaveFormat), 0, 0, CALLBACK_NULL) PRINT "返回值:"; c& IF c& = 0 THEN PRINT "音频输入设备打开成功"
关键修改说明
- 所有API参数改为
LONG类型,加ByVal关键字明确按值传递,指针类参数通过VARPTR()函数获取变量的内存地址传入。 - 修正了结构体变量名的笔误,确保传入的结构体参数有效。
- 设备ID默认改为0,调用系统默认音频输入设备,避免设备枚举错误导致的ID无效问题。
内容的提问来源于stack exchange,提问作者Claudiu Claus
相关产品推荐
相关产品推荐

