简体   繁体   English

如何从Jython脚本调用C函数?

[英]How do I call a C Function from a Jython script?

I am creating a GUI using Jython. 我正在使用Jython创建GUI。 I want to program my logic in C. How could I can call a C Function from my Python Code. 我想用C语言编写逻辑。如何从Python代码中调用C函数。 Sorry if this a newbie question, but I have never worked with linking files except Sparc Assembly from C. 抱歉,这是一个新手问题,但是除了C的Sparc Assembly之外,我从未使用过链接文件的工作。

Jython cannot use ctypes , or C extension modules (whether built manually, or with Cython, or otherwise). Jython不能使用ctypes或C扩展模块(无论是手动生成的,还是与Cython生成的)。

The way to do this is the same way as in Java: Through a JNI bridge. 这样做的方法与Java中的方法相同:通过JNI桥。

First, you write a C++ wrapper that talks to the so, and uses functions from <jni.h> to implement functions like this: 首先,您编写一个与so对话的C ++包装器,并使用<jni.h>中的函数来实现如下功能:

JNIEXPORT void JNICALL _PACKAGE(bar)(JNIEnv *env, jclass cls, jint i) {
    if (bar(i)) {
        throwPyFromErrno(env, OSError);
    }
}

Next, in Java, you define a public class full of Java wrappers around those C++ wrappers, like this: 接下来,在Java中,围绕这些C ++包装器定义一个充满Java包装器的public类,如下所示:

public class foo implements InitModule {
    public final static native void bar(int i);
}

Finally, in Jython, you can just import the class (which acts like a Python module) from its Java module and use it like any other module: 最后,在Jython中,您可以从其Java模块中导入类(其行为类似于Python模块),并像使用其他模块一样使用它:

try:
    foo.bar(3)
except OSError as e:
    print "Failed:", e

Most of this is standard JNI, but you also have to know things like how to create Jython objects. 其中大多数是标准JNI,但您还必须了解诸如如何创建Jython对象的知识。 Ideally, you'll use wrappers for that, so you can just write makePyInteger(env, value) or throwPyFromErrno(env, exctype) instead of doing all the FindClass , GetStaticMethodID , etc. stuff manually. 理想情况下,您将为此使用包装器,因此只需编写makePyInteger(env, value)throwPyFromErrno(env, exctype)而不是手动执行所有FindClassGetStaticMethodID等工作。

I don't have any tutorials to recommend. 我没有推荐的教程。 But see jnios for a nice-sized example. 但是请参阅jnios以获得一个不错的示例。 The O'Reilly book's Chapter 25. Extending and Embedding Jython seems like it might be a decent primer (although I haven't read it). 奥赖利(O'Reilly)书第25章。扩展和嵌入Jython似乎很不错(尽管我还没看过)。 You'll probably want to read a tutorial on using JNI for Java before trying to tackle Jython. 在尝试解决Jython之前,您可能需要阅读有关使用JNI for Java的教程。

A different way to solve this problem is to break your single program into two pieces. 解决此问题的另一种方法是将单个程序分为两部分。

The GUI program runs in Jython. GUI程序在Jython中运行。 When it needs to call the C code, it does that by running a worker program. 当需要调用C代码时,它将通过运行工作程序来实现。

The worker program runs in CPython or PyPy, so it can use any of the usual techniques for talking to C libraries: ctypes , cffi , a custom C extension module (maybe using Cython , Boost.Python , SWIG , SIP , …), Weave , etc. worker程序在CPython或PyPy中运行,因此它可以使用任何与C库通信的常用技术: ctypescffi自定义C扩展模块 (也许使用CythonBoost.PythonSWIGSIP …), Weave


For a simple case, where you just need to call one function, pass it a few strings, and get back a string, it's as trivial as this: 在一个简单的例子中,您只需要调用一个函数,将其传递几个字符串,然后取回一个字符串,就这么简单:

import subprocess

def my_function(*args):
    return subprocess.check_output(['python', 
                                    '/path/to/worker/script.py'] + args)

(Note that there are a few bugs with subprocess in older versions of Jython, especially on OS X and Windows. If you run into a problem, 2.5.4 and 2.7.0, which are currently in RC and beta stages, respectively, have probably fixed it.) (请注意,在较早版本的Jython中,尤其是在OS X和Windows上,存在一些subprocess错误,如果遇到问题,当前处于RC和Beta阶段的2.5.4和2.7.0分别具有可能修复了它。)


If you need to make lots of calls one at a time throughout the life of your program, you'll probably want to keep the worker script running in the background, and use some form of RPC to talk to it. 如果您需要在程序的整个生命中一次进行多次调用,则可能需要使worker脚本在后台运行,并使用某种形式的RPC与之对话。 This blog post shows how to do it using the bjsonrpc library. 这篇博客文章显示了如何使用bjsonrpc库执行此操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM