使用Cython编译外部C函数后,Python导入模块无法识别函数求助
解决Cython导入外部C函数后找不到的问题
看起来你踩了Cython里一个很常见的坑——cdef extern声明的外部C函数默认是仅Cython内部可见的,Python解释器根本看不到它,所以导入模块后才会找不到这个函数。下面给你一步步解决的办法:
1. 给外部C函数套一个Python可见的包装层
修改你的Cython-C.pyx文件,把外部C函数用def关键字包装成一个Python能调用的函数:
# Cython-C.pyx # 声明外部C函数(这一步只是让Cython知道这个函数的存在,Python看不到它) cdef extern from "svar.h": unsigned long long int svar() # 包装成Python可访问的函数 def py_svar(): return svar()
这样Python脚本里就可以通过调用py_svar()来间接触发外部的C函数svar()了。
2. 确认setup.py正确关联了C代码文件
如果你的svar()函数是写在单独的.c文件(比如svar.c)里的,一定要在setup.py的sources列表里加上这个文件,不然编译的时候会漏掉实现导致链接错误(你说编译成功,可能已经加了,但再核对下):
# setup.py from distutils.core import setup from distutils.extension import Extension from Cython.Build import cythonize ext_modules = [ Extension( "Cython-C", # 生成的模块名称,要和你导入时用的名字一致 sources=["Cython-C.pyx", "svar.c"], # 把你的C实现文件也加进来 extra_compile_args=["-O3"], # 可选,开启编译优化 ) ] setup( name="Cython-C", ext_modules=cythonize(ext_modules) )
3. 重新编译并测试
执行编译命令:
python setup.py build_ext --inplace
然后在Python脚本里导入模块调用包装后的函数:
import Cython_C # 注意如果模块名有横杠,Python里要换成下划线,或者直接把模块名改成CythonC更方便 print(Cython_C.py_svar())
额外说明
- 为什么
cdef的函数Python看不到?因为cdef是Cython用来定义C层级函数/变量的关键字,这些定义会被编译成纯C代码,不会生成Python可调用的接口。只有def或cpdef定义的函数,才会被暴露到Python的模块命名空间里。 - 如果你的头文件
svar.h不在当前工作目录,要在Extension里加上include_dirs参数指定头文件路径;如果是链接预编译的静态/动态库,还要加上library_dirs和libraries参数。
内容的提问来源于stack exchange,提问作者CupinaCoffee
相关产品推荐
相关产品推荐

