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 do it compiling on the command line?
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.
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
Write PyObjC wrapper around python code
Execute code declaring PyObjC wrapper to add these definitions to the ObjC runtime
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.
Google is your friend. Performing a search on the string "Cocoa Python" quickly turned up PyObjc.
Related
I have a python app and java app. The python app generates input for the java app and invokes it on the command line.
I'm sure there must be a more elegant solution to this; just like using JNI to invoke C code from Java.
Any pointers?
(FYI I'm v. new to Python)
Clarification (at the cost of a long question: apologies)
The py app (which I don't own) takes user input in the form of a number of configuration files. It then interprits these and farms work off to a number of (hidden) tools via a plugin mechanism. I'm looking to add support for the functionality provided by the legacy Java app.
So it doesn't make sense to call the python app from the java app and I can't run the py app in a jython environment (on the JVM).
Since there is no obvious mechanism for this I think the simple CL invocation is the best solution.
Sorry to ressurect the thread, but there was no accepted answer...
You could also use Py4J. There is an example on the frontpage and lots of documentation, but essentially, you just call Java methods from your python code as if they were python methods:
>>> from py4j.java_gateway import JavaGateway
>>> gateway = JavaGateway() # connect to the JVM
>>> java_object = gateway.jvm.mypackage.MyClass() # invoke constructor
>>> other_object = java_object.doThat()
>>> other_object.doThis(1,'abc')
>>> gateway.jvm.java.lang.System.out.println('Hello World!') # call a static method
As opposed to Jython, Py4J runs in the Python VM so it is always "up to date" with the latest version of Python and you can use libraries that do not run well on Jython (e.g., lxml). The communication is done through sockets instead of JNI.
Disclaimer: I am the author of Py4J
Take a look at Jython. It's kind of like JNI, but replace C with Python, i.e. you can call Python from Java and vice versa. It's not totally clear what you're trying to do or why your current approach isn't what you want.
Wrap your Java-Code in a Container (Servlet / EJB).
So you don´t loose time in the vm-startup and you go the way to more service-oriented.
For the wraping you can use jython (only make sense if you are familiar with python)
Choose a communication-protocoll in which python and java can use:
json (see www.json.org)
rmi (Python: JPype)
REST
SOAP (only for the brave)
Choose something you or your partners are familliar with!
If you really want to embed your Java app within your Python process, have a look at JPype. It provides access to Java through JNI.
How about using swig: http://www.swig.org/Doc1.3/Java.html ?
Give JCC a try http://pypi.python.org/pypi/JCC/2.1
JCC is a code generator for calling Java directly from CPython. It supports CPython 2.3+, several JREs (Sun JDK 1.4+, Apple JRE 1.4+, and OpenJDK 1.7) on OS X, Linux, Solaris, and Windows. It's produced by the Open Source Application Foundation (OSAF, the people making Chandler) and is released under an Apache-style license.
From the package description:
JCC is a C++ code generator for producing the glue code necessary to call into Java classes from CPython via Java's Native Invocation Interface (JNI).
JCC generates C++ wrapper classes that hide all the gory details of JNI access as well Java memory and object reference management.
JCC generates CPython types that make these C++ classes accessible from a Python interpreter. JCC attempts to make these Python types pythonic by detecting iterators and property accessors. Iterators and mappings may also be declared to JCC.
I have a legacy (but still internally maintained) application written in C++ which handles some hardware, interacts with databases, receives commands via serial line or socket... in short it does a non-trivial amount of work.
This application runs under Linux (ARM/Buildroot).
Now the need is to revamp the control interface adding a RESTful API.
I am exploring the possibility to do so via a Python extension.
Note I am a C++/java programmer and I'm not really proficient in Python, but I know the basics.
General idea would be:
Start a Python interpreter as a thread in the C++ application.
Use Flask/jinja2 (or just plain Bottle) to handle incoming RESTful requests.
Expose a few (perhaps just one) C++ class to Python.
Call from Python the appropriate C++ methods to perform the required actions.
I studied the official documentation (mainly pertaining plain C) and several alternatives, including:
Boost.Python (possibly too heavy for our limited hardware)
pybind11 (seems concerned only in extending Python, not embedding it).
http://www.codeproject.com/Articles/11805/Embedding-Python-in-C-C-Part-I (deals only with embedding, without giving Python access to C++ classes).
Question are:
does this make any sense?
what is the least intrusive way (if any) to achieve this?
which lib/framework is advised to use?
is there some tutorial project along these lines?
I know the question is quite broad, but I hope to narrow it as soon as the first comments will point me in the right direction.
Can you do it the other way around - embed your C++ code in Python program? This way it would be more prepared for moving existing functionality Python like you said.
Python makes a lot of things easier (faster to develop, easier to maintain) - communication with databases, libraries (if hey have Python wrappers), process/thread management... Keep in C++ just the stuff that needs to be in C++, like dealing with hardware, C/C++-only libraries, CPU-heavy code.
Have a look at Cython for embedding C++ in Python. Cython is basically a compiler from Python-like language to a .c/.cpp file that "just" calls the Python C API, so it can be used from "normal" Python code, but can also call other C/C++ code.
Alternative: Implement an API in the C++ application and create a separate Python application that uses this API. By API I don't mean REST API, but something more low-level - RPC, ZeroMQ, plain sockets...
I have a Delphi Win32 program. I want to "expose" somehow app structures and procedures via Python module. E.g. module my_api must expose public items for my app structures/methods. This module must "sit" in memory only.
Then I want, in the same app, to call Python scripts (using Python dll) which can import my_api and call my app methods.
How to do it.
You're asking for two things here, which often go together.
First, you want to extend the Python interpreter, adding types and functions and so forth that Python code can use.
Second, you want to embed the Python interpreter in your app, so it can run Python scripts (which can use your extension modules).
Assuming you want to use CPython (the usual Python interpreter), the tutorial Extending and Embedding the Python Interpreter is part of the docs.
You may want to look at other options that help make the extending side easier—for example, you can use Cython to write the bridge code in a near-Python language instead of C, or Boost.Python to write it in nice C++ that takes care of most of the boilerplate for you, or SWIG to try to generate it automatically, or ctypes to avoid writing a bridge in the first place. But it's worth learning the underlying mechanism first.
You may have heard of Python 4 Delphi by now, and if you haven't you can look it up here. https://code.google.com/p/python4delphi/. There are quite a few tutorials on the internet e,g http://www.atug.com/andypatterns/pythonDelphiTalk.htm
I got curious and have been reading about GUI development using Python for the past hour. After reading documentation of wxPython, PyQt, Nokia's Python bindings for Qt along with Tkinter a question came to my mind.
When I create a console application with Python, it runs using the embedded Python interpreter (which I assume is usually if not always in my case cpython).
So I was wondering, what's the case with these "widget toolkits"?
How is the Python code executed and what interprets it (or executed it)?
Which part of my Python code is interpreted using the Python
interpreter?
Or does the Python code get lexically analysed and then parsed by the widget's
toolkit which then interpretes and executes (or compile during build)?
I am looking forward to understanding what goes on in the background in comparison with Python applications' (a bit simpler to understand) interpretation with the Python interpreter.
Thank you.
PS. To whichever genius thinks that this question deserves to be closed;
A lot of people wonder the internals of external libraries and systems. Especially those which are not as simple as they look. There currently is not any question explaining this on SE.
This is just a really generalized high-level explanation about "GUI toolkits"...
Lets say you decide to use the Qt framework. This framework is written in C++. There are two different python bindings that can be used, allowing one to write a GUI application in python against the same API as the C++ version.
The python bindings provide a wrapping around calls into the C++ code. PyQt4 for instance uses sip, while PySide uses shiboken. These are just language wrapping tools that take specifications for how to map between the C++ objects and their intended python interface.
Ok, so you start using PyQt... All of the code you write has to pass through the python interpreter. Some of it may be pure python. Some of it will call into C++ libs to create things like your widgets. In Qt, there will be a C++ pointer associated with the python instance counterpart.
It is the C++ layer that is then communicating with the window manager of your platform, to turn platform-independent API calls into something platform specific, like how to exactly draw a button or menu.
Whether you create a console only or GUI based python application, it all goes through the python interpreter to interpret your python code. Something must interpret the python language for you.
This question already has an answer here:
Closed 11 years ago.
Possible Duplicate:
Calling Python from Objective-C
I'm a long-time Python programmer and short-time Cocoa programmer. I'm just getting started with PyObjC and it's really amazing how easy it it is to get stuff done. That said, I wanted to try using pure ObjC for my controller with PyObjC models. I might be enjoy letting Python be Python and Objective-C be Objective-C. I figured it was worth a try, anyways.
Except I can't figure out or find anything about how to call Python from Objective-C, only the other way around. Can someone point me to any resources on this? (Maybe it's on the PyObjC site but I just don't know what I'm looking for?)
Edit: I'm most interested, at the basic level, in being able to call a Python module and get some native ObjC data types back.
There are several possible approaches. The most tempting is to use py2app to compile a loadable bundle from your python code from which you can access the principal class using NSBundle. Unfortunately, this use case hasn't gotten much love from the py2app developers, and I've found several bugs in 10.5 and 10.6, including a rather nasty memory leak when passing data from python back in to Objective-C. I wouldn't recommend using py2app at thist point.
The second approach is invert the embedding. Write a Python cocoa app and load your Objective-C code from a bundle at startup (even in main()). If you already have a large Objective-C app, this may take a bit of work. The only downside, that I'm ware of, is that you won't be able to use GC in your Objective-C code, but this is really a universal limitation in working with PyObjC.
Finally, you can instantiate a python interpreter in your Objective-C code to load your python code. This is obviously more involved, but may the best option if you already have a large Objective-C codebase into which you want to inject your python code. The main.m file from the Python-Cococa application template in Xcode is a good place to start to see this in action.
Whoops, guess I should've searched a bit more:
Calling Python from Objective-C