[Pythonmac-SIG] ctypes and OS X CF types?

Daniel Miller daniel at keystonewood.com
Mon Oct 22 18:07:38 CEST 2007


AFAIK you don't need to do anything special (i.e. write "ctypes  
definitions") to call the CF functions with ctypes. Just call them.  
Here's a snippet of code that I use to open a PDF document and get  
the number of pages:


from ctypes import cdll, byref, c_void_p, c_int, c_uint, c_float,  
c_double
from ctypes.util import find_library

cf = cdll.LoadLibrary(find_library("ApplicatonServices"))

filename = "/path/to/document.pdf"

kCFAllocatorDefault = None
kCFURLPOSIXPathStyle = 0

# open pdf document
fileref = None
fileurl = None
try:
     fileref = cf.CFStringCreateWithCString(None, filename, 0)
     fileurl = cf.CFURLCreateWithFileSystemPath(
         kCFAllocatorDefault,
         fileref,
         kCFURLPOSIXPathStyle,
         0
     )
     pdf = cf.CGPDFDocumentCreateWithURL(fileurl)
     if not pdf:
         raise PrintError("cannot open PDF document: %s" % filename)
finally:
     if fileurl:
         cf.CFRelease(fileurl)
     if fileref:
         cf.CFRelease(fileref)

numpages = cf.CGPDFDocumentGetNumberOfPages(pdf)

if pdf:
     cf.CGPDFDocumentRelease(pdf)



My experience with developing code like this is that it takes a lot  
of patience and trial and error to get it stable. Remember that  
you're dealing with C functions and pointers (it's called ctypes for  
a reason), which are not nearly as forgiving as normal Python  
functions and objects. For example, calling a C function with the  
wrong argument types will generally cause a cold hard segfault rather  
than give you a nice stack trace with some indication of what caused  
the error. When all else fails read the documentation for the library  
you're calling...again.

~ Daniel




More information about the Pythonmac-SIG mailing list