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

时间:2013-06-07 22:43:26

标签: java python compilation jython

我正在使用Jython创建GUI。我想在C中编写我的逻辑。我怎么能从我的Python代码中调用C函数。很抱歉,如果这是一个新手问题,但我从未使用过链接文件,除了Sparc Assembly from C。

2 个答案:

答案 0 :(得分:4)

Jython不能使用ctypes或C扩展模块(无论是手动构建,还是使用Cython构建,或其他方式)。

执行此操作的方式与Java中的方式相同:通过JNI桥。

首先,编写一个与之对话的C ++包装器,并使用<jni.h>中的函数来实现这样的函数:

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

接下来,在Java中,您将围绕这些C ++包装器定义一个充满Java包装器的public类,如下所示:

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

最后,在Jython中,您可以从其Java模块导入类(其作用类似于Python模块),并像任何其他模块一样使用它:

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

这大部分都是标准的JNI,但你也必须知道如何创建Jython对象。理想情况下,您将使用包装器,因此您只需编写makePyInteger(env, value)throwPyFromErrno(env, exctype)而不是手动执行所有FindClassGetStaticMethodID等内容。

我没有任何教程可供推荐。但请参阅jnios以获取一个很好的示例。 O'Reilly的书Chapter 25. Extending and Embedding Jython似乎可能是一个不错的入门书(尽管我还没读过)。在尝试解决Jython之前,您可能希望阅读有关使用JNI for Java的教程。

答案 1 :(得分:0)

解决此问题的另一种方法是将您的单个程序分成两部分。

GUI程序在Jython中运行。当需要调用C代码时,它通过运行工作程序来实现。

工作程序在CPython或PyPy中运行,因此它可以使用任何常用技术与C库进行通信:ctypescffia custom C extension module(可能使用{{3} }},CythonBoost.PythonSWIG,...),SIP等。


对于一个简单的情况,你只需要调用一个函数,传递几个字符串,然后返回一个字符串,它就像这样简单:

import subprocess

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

(请注意,旧版Jython中存在subprocess的一些错误,特别是在OS X和Windows上。如果遇到问题,2.5.4和2.7.0,目前在RC中和β阶段分别可能已经解决了。)


如果您需要在程序的整个生命周期中一次拨打一个电话,您可能希望让工作脚本在后台运行,并使用某种形式的RPC与之通信。 Weave显示了如何使用bjsonrpc库。