如何从 CPython 调用 java 对象和函数?
我有一个 python 程序,它在 CPython 实现上运行,并且在其中我必须调用 java 程序中定义的函数。 我怎样才能做到这一点?
如果能够使用一些 java 对象那就太好了。
Jython 不是一个选择。 我必须在 CPython 中运行 python 部分。
I have a python program, which runs on the CPython implementation, and inside it I must call a function defined in a java program. How can I do this?
It would be nice to be able to use some java objects too.
Jython is not an option. I must run the python part in CPython.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
最简单的事情是
为你的java“函数”编写一个简单的CLI。 (没有这样的东西,所以我假设您实际上指的是 Java 类的方法函数。)
以此为入口点编译并构建一个可执行 JAR 文件。 叫它
ExposeAMethod.jar
从子进程创建的命令中调用此函数。
这是最小值。 而且确实不多。 我数了数 6 行 java,3 行 Python,你就可以启动并运行了。
如果要将参数传递给该 Java 类构造函数或方法函数,则必须多编写几行代码。 你有两个选择。
从 stdin 读取参数,将结果写入 stdout。 这相对简单并且性能非常好。
将参数解析为 Java 的命令行选项,并将结果写入 stdout。 这稍微困难一些,但概括起来非常好。 额外的好处是,您现在拥有一个可以重用的有用的命令行 Java 程序。
The easiest thing to do is
Write a trivial CLI for your java "function". (There's no such thing, so I'll assume you actually mean a method function of a Java class.)
Compile and build an executable JAR file with this as the entry point. Call it
ExposeAMethod.jar
Call this from a command created by subprocess.
This is the minimum. And it's really not much. I count 6 lines of java, 3 lines of Python and you're up and running.
If you want to pass arguments to this Java class constructor or method function, you'll have to write a few more lines of code. You have two choices.
Read the arguments from stdin, write the results on stdout. This is relatively easy and performs really well.
Parse the arguments as command-line options to Java, write the results on stdout. This is slightly harder, but generalizes very nicely. The bonus is that you now have a useful command-line Java program that you can reuse.
为复活该线程而道歉,但我认为我有一个更好的答案:-)
您也可以使用 Py4J 它有两部分:一个在 CPython(或任何与此相关的 Python 解释器)中运行的库和一个在您要调用的 Java VM 上运行的库。
首页上有一个示例和大量文档,但本质上,您只需从 Python 代码中调用 Java 方法,就像它们是 Python 方法一样:
通信是通过套接字而不是 JNI 完成的。
免责声明:我是 Py4J 的作者
Apologies for resurrecting the thread, but I think I have a better answer :-)
You could also use Py4J which has two parts: a library that runs in CPython (or any Python interpreter for that matter) and a library that runs on the Java VM you want to call.
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:
The communication is done through sockets instead of JNI.
Disclaimer: I am the author of Py4J
您必须创建一个嵌入 Java 的 python C 扩展 - 基于类似 http://www.javaworld.com/javaworld/jw-05-2001/jw-0511-legacy.html 否则你将不得不在单独的子进程中启动java。
You'll have to create a python C extension that embeds Java - based on something like http://www.javaworld.com/javaworld/jw-05-2001/jw-0511-legacy.html or else you'll have to start java in a separate subprocess.
如果您不想编写自己的 JNI/C 路线。
另一个选择是使用 jpype,对我来说,它总是用来访问 Oracle 数据库,因为在 PC 上安装 oracle c 驱动程序是一件麻烦事。
您可以执行类似的操作(来自文档):
它已经有一段时间没有更新了,并且文档中没有太多内容,但它确实工作得相当好。
If you don't want to go the write your own JNI/C route.
The other option is to use jpype which for me is always what I use to access Oracle databases becuase installing the oracle c drivers on a PC is a pita.
You can do stuff like (from docs):
It hasn't been updated in a while and there isn't much in the way of documentation but it does work reasonably well.
我不知道Python,但上次我必须从C 应用程序(NT 服务)调用java,我必须加载
jvm.dll
。 查看 JNI 文档。始终会调用。
另外,如果您不关心性能,则
I don't know for Python, but last time I had to call java from C application (NT service) I had to load
jvm.dll
. Take a look at JNI documentation.Also, you call always call
if you are not concerned about performance.
看看我们的项目 python-javabridge。 它是 JNI 的 Python 包装器,被 CellProfiler 大量使用。 它提供对 JNI 的低级访问和对 Java 对象的基于反射的高级访问。
Look at our project python-javabridge. It's a Python wrapper around the JNI, heavily used by CellProfiler. It offers both low-level access to the JNI and a high-level reflection-based access to Java objects.