【问题标题】:Compiling multiple C files with Cython使用 Cython 编译多个 C 文件
【发布时间】:2017-09-19 14:29:28
【问题描述】:

如何使用 Cython 进行编译,这是来自文件 simulate_fast.c 的 C 函数,这还取决于进一步的 C 文件 matrix.crandom_generator.c。这似乎必须是 Cython 的常见用法,但在阅读了文档后,我仍然无法弄清楚如何去做。我的目录包含以下文件

matrix.c
matrix.h
random_generator.c
random_generator.h
simulate_fast.c
simulate_fast.h
test.c
simulate_fast_c.pyx
setup.py

matrix.crandom_generator.c 文件包含独立功能。 simulate_fast.c 文件同时使用了这两种方法,并且包含了我想要暴露给 Python 的函数 simulate()test.c 文件测试所有 C 功能是否正确运行,即我可以执行

$ gcc test.c simulate_fast.c matrix.c random_generator.c -o test

编译成可以工作的test 可执行文件。

我现在的问题是尝试用 Cython 编译它。我的.pyx 文件是

cimport cython

cdef extern from "simulate_fast.h":
    int simulate()

def simulate_cp():
    return simulate()

然后我使用基本的setup.py

from distutils.core import setup
from Cython.Build import cythonize
from Cython.Distutils import build_ext
import numpy as np

setup(
    name='simulate_fast',
    ext_modules = cythonize(["simulate_fast_c.pyx"]),
    include_dirs=[]
)

但是,如果我尝试使用来编译它

python3 setup.py build_ext --inplace

我收到一个错误

In file included from simulate_fast_c.c:492:0:
simulate_fast.h:89:28: error: field ‘RG’ has incomplete type
    struct RandomGenerator RG;

其中结构RandomGeneratorrandom_generator.h 中声明。

我如何告诉编译器我们在编译时还必须考虑matrixrandom_generator 文件。

更新

如果按照 cmets 中的ead 所说,我在simulate_fast.h 中包含random_generator.hmatrix.h,那么程序现在可以编译。但是,当我尝试在 Python 中导入 simulate_fast_c 模块时,我得到一个 ImportError:

undefined symbol: simulate

此外,如果我将simulate_fast.pyx 中的外部声明行更改为

cdef extern from "simulate_fast.c":
    int simulate()

然后我得到一个导入错误

undefined symbol: get_random_number

这是random_generator.h中的一个函数

【问题讨论】:

  • 看起来simulate_fast.h不是自包含的,在simulate_fast.h中包含random_generator.h
  • 确实如此,尽管我仍然收到错误消息,因此我可以更新问题。出于好奇,为什么我需要在使用 Cython 而不是使用 gcc 时将 random_generator.h 包含在 simualte_fast.h 标头中?
  • 一种或另一种方式的simulate_fast.c 包括random_generator.h - 它不关心它是来自simulate_fast.h 还是其他地方......
  • 我明白(为什么它有效),我不明白为什么它以前没有用 Cython 编译,但在用 gcc 编译 test.c 时却很好。
  • 在这个答案中查看我的 setup.py:stackoverflow.com/a/46271641/5769463 您需要将所有 c 文件添加到源(但不需要整个 c++ 内容)

标签: cython


【解决方案1】:

cythonized 模块必须链接到包含已编译 C 代码的共享库或嵌入它。实现后者的一种方法是将 C 源代码列为“扩展”,然后将此扩展传递给 cythonize 命令,如 Cython's documentation

中所述

链接中的示例 setup.py 文件可以总结为(以导入为模):

setup(
    ext_modules = cythonize(Extension("simulate_fast", ["matrix.c", "random_generator.c", "simulate_fast_c.pyx"]))
)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-20
    • 1970-01-01
    • 2011-02-05
    • 1970-01-01
    • 1970-01-01
    • 2011-05-24
    • 2023-03-08
    • 1970-01-01
    相关资源
    最近更新 更多