Call from Objective-C into Python

后端 未结 3 1160
轻奢々
轻奢々 2021-02-10 18:48

bbum posted an outline of how to do this, but I\'m unable to complete the details. Where does the Python code go, and how will my Objective-C code know about it? How would I d

相关标签:
3条回答
  • 2021-02-10 19:03

    Google is your friend. Performing a search on the string "Cocoa Python" quickly turned up PyObjc.

    0 讨论(0)
  • 2021-02-10 19:12

    Unfortunately the story for using Python via PyObjC from within an Objective-C app is not very good at the moment. py2app which ships with PyObjC can compile loadable bundles (i.e. can be loaded via NSBundle), which seems like the best approach: define an NSObject subclass in python that implements a protocol (obtained via objc.protocolNamed) that you define in Objective-C, then compile this python file into a loadable bundle via py2app (which uses a standard setup.py). Unfortunately, py2app hasn't had much love, especially the plugin (loadable bundle) target, and a serious memory leak was introduced sometime around 10.5 such that any data passed from python to Objective-C from a py2app-compiled bundle leaks. Yuck.

    PyObjC manipulates the Objective-C runtime in accordance with the ObjC-related code executed in Python, thus to be able to call python code from Objective-C, the general outline goes like

    1. Write PyObjC wrapper around python code
    2. Execute code declaring PyObjC wrapper to add these definitions to the ObjC runtime
    3. Call PyObjC wrapper from Objective-C. Because it's declared at runtime, the symbols aren't available at compile time, so you'll have to use NSClassFromString et al. to instantiate the class. It's helpful to declare a @protocol with the appropriate methods so that the Objective-C compiler doesn't complain about missing methods.

    If you have flexibility, the best option is to use the Cocoa-Python app templates (i.e. create a Python app), and then load your Objective-C code as a loadable bundle from within Python. This takes care of managing the Python interpreter for you.

    Otherwise, with the code in main.m of the Cocoa-Python app template, you should be able to create a Python interpreter, execute your PyObjC code and then continue on. Obviously, the interpreter needs to be kept running so that your python code can execute, so you'll likely have to do this from a separate thread. As you can see this can get a little hairy. Better to go with the Python app, as described above.

    Keep in mind that PyObjC is not guaranteed to play well with the Objective-C garbage collector, so all of these options require that your Objective-C code not use GC.

    0 讨论(0)
  • 2021-02-10 19:14

    Source here:

    Calling Python From Objective-C

    I have posted a full explanation of how to do this to my weblog as it is quite a bit longer than something I would post here.

    The abstract summary remains the same: use an abstract class to provide the type information necessary to make the C compiler happy and the metadata necessary to make the bridge happy.

    0 讨论(0)
提交回复
热议问题