在C中使用Cython调用Python代码

2 投票
1 回答
1720 浏览
提问于 2025-04-17 22:36

我正在尝试从C语言中调用一些Python代码,并且我在按照cython用户指南来做这件事。

我有一个Cython脚本,叫做modulename.pyx,它的内容是这样的(摘自用户指南):

cdef public struct Bunny: # public type declaration
    int vorpalness

cdef public int spam # public variable declaration

cdef public void grail(Bunny b): # public function declaration
    print "Ready the holy hand grenade"

我还有一个C程序,叫做main.c,它的内容也是这样的(同样来自指南):

#include <Python.h>
#include "modulename.h"

int main() {
  Py_Initialize();
  initmodulename();
  struct Bunny b;
  grail(b);
  Py_Finalize();
}

我尝试了多种方法来编译这些代码,但都没有成功。我可以通过cython modulename.pyx把.pyx文件编译成C代码,这样会生成modulename.cmodulename.h。问题出现在我想把这些生成的文件和我的C程序一起编译和链接的时候。

以下是我尝试过的一个例子:

cc -fno-strict-aliasing -fno-common -dynamic -g -Os -pipe -fno-common -fno-strict-aliasing -fwrapv -DENABLE_DTRACE -DMACOSX -DNDEBUG -Wall -Wstrict-prototypes -DNDEBUG -g -fwrapv -Os -Wall -Wstrict-prototypes -DENABLE_DTRACE -pipe -I/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c main.c modulename.h modulename.c

结果给了我这些错误:

modulename.h:25:32: error: expected function body after function declarator
__PYX_EXTERN_C DL_IMPORT(void) grail(struct Bunny);
                           ^
modulename.h:27:31: error: expected function body after function declarator
__PYX_EXTERN_C DL_IMPORT(int) spam;
                          ^
modulename.h:32:1: error: unknown type name 'PyMODINIT_FUNC'
PyMODINIT_FUNC initmodulename(void);
^
3 errors generated.

我想要的是一些指导,帮助我让这个例子能够正常工作,或者指引我找到一些示例代码,展示如何用Cython从C中调用Python代码。

1 个回答

1

好的,我找到了问题所在。问题是我在给编译器的参数中包含了modulename.h这个文件。把它去掉后,其他的代码就可以正常运行了,连main.cmodulename.pyx都不用改动。而且,并不是所有的参数都是编译器需要的。在我的电脑上(Mac OS 10.9),编译上面的代码最简单的方法是:

编译:
cc -c main.c modulename.c -I/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7

链接:
cc -L/System/Library/Frameworks/Python.framework/Versions/2.7/lib -L/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/config -lpython2.7 -ldl main.o modulename.o -o main

撰写回答