2

我正在使用 Jython 创建一个 GUI。我想用 C 编写我的逻辑。我怎么能从我的 Python 代码中调用 C 函数。对不起,如果这是一个新手问题,但我从来没有使用过链接文件,除了来自 C 的 Sparc 程序集。

4

2 回答 2

4

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

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

首先,您编写一个与 so 对话的 C++ 包装器,并使用函数 from<jni.h>来实现如下函数:

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

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

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)orthrowPyFromErrno(env, exctype)而不是手动执行所有FindClass,GetStaticMethodID等内容。

我没有任何教程可以推荐。但是请参阅jnios以获得一个不错的示例。O'Reilly 书的第 25 章。扩展和嵌入 Jython似乎是一本不错的入门书(尽管我还没有读过)。在尝试处理 Jython 之前,您可能需要阅读有关使用 JNI for Java 的教程。

于 2013-06-07T23:00:54.810 回答
0

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

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

工作程序在 CPython 或 PyPy 中运行,因此它可以使用任何常用技术与 C 库对话:、、ctypes定义 C 扩展模块(可能使用CythonBoost.PythonSWIGSIP ……)、Weave等.cffi


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

import subprocess

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

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


如果您需要在程序的整个生命周期中一次进行大量调用,您可能希望让工作脚本在后台运行,并使用某种形式的 RPC 与其对话。这篇博客文章展示了如何使用bjsonrpc库来做到这一点。

于 2013-06-26T19:54:01.080 回答