1

基本上我想PlaySound()在 ctypes 中使用该函数。

是的,我知道 winsound 模块是基于它构建的,我可以使用它,但我有理由不这样做 :)


在 CI 中会这样调用函数:

PlaySound("sound.wav", NULL, SND_FILENAME);

我有我的 Python 脚本等价物:

import ctypes

winmm = ctypes.WinDLL('winmm.dll')

winmm.PlaySound("sound.wav", None, 0x20000)

我运行它,没有返回错误,但声音也没有播放。


我怀疑问题出在十六进制值 ( 0x20000) 上,因为其他一切似乎都很好。我得到了这样的值:

import winsound
print(hex(winsound.SND_FILENAME))

或者以不同的方式:

import ctypes, winsound

winmm = ctypes.WinDLL('winmm.dll')

winmm.PlaySound("sound.wav", None, winsound.SND_FILENAME)

那么我怎样才能让它工作以便我的文件播放呢?

4

2 回答 2

1

在 Windows 中,函数有 Unicode 和 ANSI 版本。文档表明文件名是LPCTSTR. 对于定义为的 ANSI 版本,LPCSTR对于 Unicode,它是LPCWSTR.

这是调用 Windows 函数的正确方法。通常你想要W函数的版本。定义.argtypes并且.restype也将有助于错误检查。正如您所发现的,您可以传递错误的类型并且它不起作用。.argtypes定义后,不兼容的类型将被捕获。

from ctypes import *
from ctypes import wintypes as w

dll = WinDLL('winmm')

dll.PlaySoundW.argtypes = w.LPCWSTR,w.HMODULE,w.DWORD
dll.PlaySoundW.restype = w.BOOL

SND_FILENAME = 0x20000

# Call it with a Unicode string and it works.
dll.PlaySoundW('sound.wav',None,SND_FILENAME)

# Call it with a byte string and get an error since `.argtypes` is defined.
dll.PlaySoundW(b'sound.wav',None,SND_FILENAME)

输出(声音播放后):

Traceback (most recent call last):
  File "C:\test.py", line 15, in <module>
    dll.PlaySoundW(b'sound.wav',None,SND_FILENAME)
ctypes.ArgumentError: argument 1: <class 'TypeError'>: wrong type

或者跳过所有工作,只使用 winsound 模块:

import winsound
winsound.PlaySound('sound.wav',winsound.SND_FILENAME)
于 2018-05-26T00:27:54.310 回答
0

尽管文档将其指定为字符串。

指定要播放的声音的字符串

在 Python 中,您实际上必须将其设为字节值。很简单:

winmm.PlaySound(b"sound.wav", None, 0x20000)
于 2018-05-25T18:49:30.037 回答