python - 将 Cython 指向 C 源文件

标签 python c cython

我有一个混合 Python、Cython 和 C 的项目,安排如下:

root
    |- src
        |- foo
            foo.c
    |- name
        name.pxd
        name.pyx
    |- include
        |- foo
            foo.h
    setup.py

内容非常简单:

foo.h:

void add(int, double *, double *, double *);

foo.c:

#include "foo/foo.h"
void add(int N, double * A, double * B, double * C) {
    for (int i = 0; i < N; i++) C[i] = A[i]+B[i];
}

名称.pxd:

cdef extern from "foo/foo.h":
    void add(int, double *, double *, double *)

名称.pyx:

import numpy as np
cimport numpy as np

cpdef cython_add(np.ndarray[np.double_t, ndim=1] A, 
                 np.ndarray[np.double_t, ndim=1] B):
    cdef int N = min(A.shape[0], B.shape[0])
    cdef np.ndarray C = np.ndarray([N],dtype=np.double)
    add(N, <double*> A.data, <double*> B.data, <double*> C.data)
    return C

设置.py:

from distutils.core import setup
from Cython.Build import cythonize

setup(
    ext_modules = cythonize("name/*.pyx", sources=["src/foo/foo.c"])
)

并使用以下命令进行编译:

CFLAGS="-I/path/to/root/include" python setup.py build_ext -i

它编译得很好,除了当我在 python 解释器中尝试 import name 时,我得到以下结果:

ImportError: dlopen(./name.so, 2): Symbol not found: _add
  Referenced from: ./name.so
  Expected in: dynamic lookup

我认为这意味着即使所有内容都已编译,Cython 实际上并未将正确的文件链接在一起。我错过了什么?

最佳答案

事实证明我必须改变两件事。我忘记告诉 name.pyx 导入 name.pxd。所以我必须将此行添加到 name.pyx 的顶部:

from name cimport add

当我在 name.pyx 本身中包含 distutils header 信息时,它也起作用,因此将这些行放在 name.pyx 的最顶部>:

#distutils: language = c
#distutils: sources = src/foo/foo.c

并像这样更改了setup.py:

from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
from numpy import get_include

extensions = [
  Extension("name", ["name/name.pyx"],
    include_dirs = ["include", get_include()])
]

setup(
  name = "name",
  ext_modules = cythonize(extensions)
)

关于python - 将 Cython 指向 C 源文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26601285/

相关文章:

Python-sqlalchemy-oracle连接无法连接到SID

c - 当我们将 "if(ptr==NULL)"用作整数指针 ptr 时,NULL 指针是否隐式转换为类型 (int*)?

检查不良做法/改进

python - 如何迭代枚举 Flag 子类中的 *distinct* 标志?

python - 根据查找更改 pandas 中的行值

python - dask:指定进程数

python - cython-distutils 与 cmake : linking against libpython?

c - 在C下的Linux ubuntu中以类似 "Jun 19 10:08"的格式打印文件的详细信息

python - 在 Python : C, Cython 或 ctypes 中包装 C 库?

exception - 在 Python 2 和 Python3 上重新引发 Cython 中的异常