Python's FFI: ctypes

Slated for inclusion in Python 2.5, ctypes offers a foreign function interface (FFI) for bring shared libraries in, and wrapping them up so that you can access them through Python. It’s actually an amazing piece of work. It supports the shared libraries on every major platform, and makes it a snap to gain access to a few functions that you may need. I recently found that we’ll need the ctypes module for a project that I’m working on (I need it for PyVISA), so I also used it solve another problem: getting the amount of free disk space under a certain path. On nix type systems, it’s easy: use os.statvfs(). On Windows, you really need access to GetDiskFreeSpaceEx(). Well, the team didn’t want to include pywin32 just to gain access to this *one function, so we used ctypes instead. That lead us to the following code snippet which implements exactly what we need on both Linux and Windows:

def get_disk_space(path):
  import sys
  if sys.platform == 'win32':
    from ctypes import windll, c_ulonglong, byref
    arg2 = c_ulonglong(0)
    arg3 = c_ulonglong(0)
    arg4 = c_ulonglong(0)
    windll.kernel32.GetDiskFreeSpaceExA(path, byref(arg2),
                                        byref(arg3), byref(arg4))
    return arg2.value
  else:
    import os
    res = os.statvfs(path)
    return long(res[0] * res[4])

The above code provides the required information, and works on both platforms. It’s easy, simple, and we didn’t have to include another module to make use of it. There is one drawback though. Going through this sort of interface can be very slow. However, we only ask for the disk space occassionally, so speed was not an issue for us.