Calling Objective C functions with ctypes

"Timothy W. Grove" <[email protected]> Thu, 19 Mar 2015 16:11:29 +0000
Newsgroups gmane.comp.python.ctypes
Message-ID <[email protected]>
I have been trying to get the following code copied from another forum 
to work on my system (OSX 10.6, 10.8, Python 3.3 installed via 
MacPorts), and it just won't. It seems to be finding the 'AppKit' and 
'objc' libraries okay, but it is not getting the classes 
'NSSpeechSynthesizer' or 'NSAutoreleasePool', so 'count' ends up as '0' 
and everything falls over from there.

I did notice from the "print voiceNames" statement that this code must 
be pre-python 3, so are there any obvious changes needed to bring this 
up to date? Thanks for any help or suggestions.

Best regards,
Tim Grove

    [from
    http://stackoverflow.com/questions/1490039/calling-objective-c-functions-from-python/1490644#1490644]
    import ctypes
    import ctypes.util

    # Need to do this to load the NSSpeechSynthesizer class, which is in
    AppKit.framework
    appkit = ctypes.cdll.LoadLibrary(ctypes.util.find_library('AppKit'))
    objc = ctypes.cdll.LoadLibrary(ctypes.util.find_library('objc'))

    objc.objc_getClass.restype = ctypes.c_void_p
    objc.sel_registerName.restype = ctypes.c_void_p
    objc.objc_msgSend.restype = ctypes.c_void_p
    objc.objc_msgSend.argtypes = [ctypes.c_void_p, ctypes.c_void_p]

    # Without this, it will still work, but it'll leak memory
    NSAutoreleasePool = objc.objc_getClass('NSAutoreleasePool')
    pool = objc.objc_msgSend(NSAutoreleasePool,
    objc.sel_registerName('alloc'))
    pool = objc.objc_msgSend(pool, objc.sel_registerName('init'))

    NSSpeechSynthesizer = objc.objc_getClass('NSSpeechSynthesizer')
    availableVoices = objc.objc_msgSend(NSSpeechSynthesizer,
    objc.sel_registerName('availableVoices'))

    count = objc.objc_msgSend(availableVoices,
    objc.sel_registerName('count'))
    voiceNames = [
       ctypes.string_at(
         objc.objc_msgSend(
           objc.objc_msgSend(availableVoices,
    objc.sel_registerName('objectAtIndex:'), i),
           objc.sel_registerName('UTF8String')))
       for i in range(count)]
    print voiceNames

    objc.objc_msgSend(pool, objc.sel_registerName('release'))

------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/

_______________________________________________
ctypes-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ctypes-users