我正在使用Jython创建GUI。我想在C中编写我的逻辑。我怎么能从我的Python代码中调用C函数。很抱歉,如果这是一个新手问题,但我从未使用过链接文件,除了Sparc Assembly from C。
答案 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)
而不是手动执行所有FindClass
,GetStaticMethodID
等内容。
我没有任何教程可供推荐。但请参阅jnios以获取一个很好的示例。 O'Reilly的书Chapter 25. Extending and Embedding Jython似乎可能是一个不错的入门书(尽管我还没读过)。在尝试解决Jython之前,您可能希望阅读有关使用JNI for Java的教程。
答案 1 :(得分:0)
解决此问题的另一种方法是将您的单个程序分成两部分。
GUI程序在Jython中运行。当需要调用C代码时,它通过运行工作程序来实现。
工作程序在CPython或PyPy中运行,因此它可以使用任何常用技术与C库进行通信:ctypes
,cffi
,a custom C extension module(可能使用{{3} }},Cython,Boost.Python,SWIG,...),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
库。