pythonwindowsdllsegmentation-faultwinmm

using winmm.dll in python to get input devices


I want to list my input devices on my windows (like microphone and etc.).

the code is here :

    from ctypes import * 
    import sys
    #printf = libc.printf
    winmm =  windll.LoadLibrary("winmm.dll")
    widn = winmm.waveInGetDevCapsA #wave in device num
    widn.restype = c_uint

    waveNum = winmm.waveInGetNumDevs 

    class LPWAVEINCAPS(Structure):
        _fields_ = [
            ("wMid",c_ushort),
            ("wPid",c_ushort),
            ("vDriverVersion",c_uint),
            ("szPname",c_wchar_p),
            ("dwFormats",c_uint),
            ("wChannels",c_ushort), 
            ("wReserved1",c_ushort),
            ]

    widn.argtypes = [
        c_uint,
        POINTER(LPWAVEINCAPS),
        c_uint
        ]

    count_devs = waveNum()

    print(count_devs)

    structLP = LPWAVEINCAPS()

    for i in range(count_devs):
        str = widn(c_uint(i),byref(structLP),c_uint(sys.getsizeof(structLP)))
        print(structLP.szPname)

The output is Segment fault and when I remove byref it gave me None as output.

help me please thank you so much :)


Solution

  • I‌ solved the problem :‌

    the problem was my string pointer, I‌ used s = create_string_buffer(b'\000' * 32) and then ("szPname", type(s)) in the structure

    from ctypes import * 
    import sys
    #printf = libc.printf
    winmm =  windll.LoadLibrary("winmm.dll")
    widn = winmm.waveInGetDevCapsA #wave in device num
    widn.restype = c_uint
    
    waveNum = winmm.waveInGetNumDevs
    
    s = create_string_buffer(b'\000' * 32)
    
    class LPWAVEINCAPS(Structure):
        _fields_ = [
            ("wMid",c_ushort),
            ("wPid",c_ushort),
            ("vDriverVersion",c_uint),
            ("szPname", type(s)),
            ("dwFormats",c_uint),
            ("wChannels",c_ushort), 
            ("wReserved1",c_ushort),
            ]
    
    widn.argtypes = [
        c_uint,
        POINTER(LPWAVEINCAPS),
        c_uint
        ]
    
    count_devs = waveNum()
    
    print(count_devs)
    
    structLP = LPWAVEINCAPS()
    
    for i in range(count_devs):
        print(sizeof(type(structLP)))
        str = widn(c_uint(i),byref(structLP),sizeof(structLP))
        print(structLP.szPname)
    #waveCaps = winmm.waveOutGetDevCaps
    waveNum.restype = c_uint
    #waveCaps.argtypes = []