11
votes

Calling Objectif C Fonctions de Python?

existe-t-il un moyen d'appeler de manière dynamique une fonction d'objectif c de Python?

Par exemple, sur le Mac, je voudrais appeler cette fonction d'objectif C xxx

sans avoir à précompiler un module de wrapper python spécial.


0 commentaires

4 Réponses :


3
votes

Vous voulez probablement pyobjc . Cela dit, je ne l'ai jamais utilisé moi-même (je n'ai jamais vu des démos), alors je ne suis pas certain que cela fera ce dont vous avez besoin.


0 commentaires

4
votes

Mac OS X à partir de 10.5 est expédié avec Python et le module OBJC qui vous permettra de faire ce que vous voulez.

Un exemple: p>

from Foundation import *

thing = NSKeyedUnarchiver.unarchiveObjectWithFile_(some_plist_file)


1 commentaires

Vous n'avez pas besoin d'importer le module OBJC, Just Foundation.



10
votes

Depuis le système d'exploitation X 10.5, OS X a été expédié avec le pont pyobjc , un pont python-objectif-c . Il utilise le Cadre de Bridgesupport pour mapper les cadres de l'objectif-C à Python. Contrairement à, MacRuby, Pyobjc est un pont classique - il existe un objet proxy sur le côté Python pour chaque objet OBJC et VISA VERSA. Cependant, le pont est assez transparent, cependant, et il est possible d'écrire des applications entières dans PyOBJC (XCode dispose d'un support de base PyOBJC, et vous pouvez télécharger l'application et les modèles de fichier pour Xcode à partir du PYOBJC SVN du lien ci-dessus). Beaucoup de gens utilisent pour les utilitaires ou pour les appliques de script / plugins. Le site de développeur d'Apple a également un Introduction pour développer des applications de cacao avec Python via Pyobjc qui est légèrement sorti. de la date, mais peut être une bonne vue d'ensemble pour vous.

Dans votre cas, le code suivant appellera [nsspeecynthesizer disponiblevoices] : xxx

qui retourne xxx

(un nscparray ponté) sur ma machine SL.


1 commentaires

Le lien d'introduction que vous avez partagé est cassé. Êtes-vous peut-être parlé de cela? opensource.apple.com/source/pyobjc/pyobjc-47/pyobjc/...



23
votes

Comme d'autres personnes ont mentionné, Pyobjc est la voie à suivre. Mais, à l'égalité des raisons, voici comment vous pouvez le faire avec CTYPES , au cas où vous Besoin de travailler sur des versions de OS X avant 10.5 qui n'ont pas installé PyObjc:

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'))


3 commentaires

Bonjour, cela se bloque sur 10.6 - toute idée de pourquoi?


@ECIR: Merci pour la pointe, je suis surpris que le code d'origine a travaillé en premier lieu. Le problème était que tous les pointeurs (pointeurs de classe et points d'instance) devaient tronquer 32 bits en raison de la manière dont les CTTYPES travaillaient, ce qui a entraîné des accidents. Pour résoudre ce problème, j'ai changé le code pour définir tous les types de résultats et les types d'arguments pour être explicitement des pointeurs.


Semble que Mavericks n'est plus expédié avec pyobjc afin que cette réponse soit à nouveau pertinente!