我正在使用 Jython 创建一个 GUI。我想用 C 编写我的逻辑。我怎么能从我的 Python 代码中调用 C 函数。对不起,如果这是一个新手问题,但我从来没有使用过链接文件,除了来自 C 的 Sparc 程序集。
2 回答
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 的教程。
解决此问题的另一种方法是将单个程序分成两部分。
GUI 程序在 Jython 中运行。当它需要调用 C 代码时,它通过运行工作程序来实现。
工作程序在 CPython 或 PyPy 中运行,因此它可以使用任何常用技术与 C 库对话:、、ctypes
自定义 C 扩展模块(可能使用Cython、Boost.Python、SWIG、SIP ……)、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
库来做到这一点。