我是Cython的新手,并且了解C / C ++编译的基础知识。
这是我想要做的事情:
有一个用C编写的相当大的库,我想在我的Python程序中加入。 (特别是它是GNUGo的板逻辑的实现。我正在尝试为它构建AI。)我需要这个例程快,并且使用Python的逻辑实现太慢了
Cython文档说我应该创建一个.pxd
文件,列出从.h
文件外部定义的方法签名。然后我应该在相应的.pyx
文件中创建一个包装类,并手动创建挂钩到上面列出的方法签名的Python端函数调用。
我遇到的问题是我想要实现的库不是像文档示例那样的单个C文件。它使用多个C文件,它们各有相互依赖关系,游戏板表示为一组全局变量,它们在整个地方定义为extern。我真的,真的不想为所有必需的C文件写.pxd
。
GNUGo文档表明我可以创建一个libboard.a
文件 - 这在概念上与.o
文件不同,有没有办法将此文件包含在Cython中?理想情况下,我希望将其视为黑盒子,让我进行方法调用,让库处理其疯狂的全局变量,并返回所需的输出。
答案 0 :(得分:0)
我不确定这是否是正确的"这样做的方法,但这就是我如何使它发挥作用。
在我的go.pxd
文件中,我从头文件board.h
列出了我需要的所有方法声明。而不是做
cdef extern from "board.h":
...
我做
cdef extern:
...
因为我不想实际包含board.h文件 - 我改为使用库libboard.a
。在该块中,我列出了我需要的所有方法。
在我的go.pyx
文件中,我cimport go
,然后在我需要使用它时执行go.method_name(args)
。在go.pyx
上运行Cython以生成go.c
工作文件,因为所有方法都已定义extern
。
最后,要将其转换为要导入的go.so
库,我有一个基本上做的Makefile
gcc -shared -pthread -fPIC -fwrapv -O2 -Wall -fno-strict-aliasing \
-I/usr/include/python2.7 go.c libboard.a -o go.so
最终的go.so
可以在Python中导入并且工作正常。
棘手的部分是我需要在链接之前用libboard.a
重新编译-fPIC
。我还需要删除一些curses.h / term.h的库调用,因为我无法使这些包含工作,但幸运的是我还不需要漂亮的打印。
一般情况下,您似乎应该能够在最后一步中链接任意.o
或.a
声明,只要您不指定它们的位置{{1}来自extern
文件。这似乎很快就会变得非常混乱,但至少它是有效的。