gpt4 book ai didi

python - 使用 Cython 传递 int 和 struct 包装 C 代码的最小示例

转载 作者:太空狗 更新时间:2023-10-29 20:30:37 26 4
gpt4 key购买 nike

我在下面显示的代码有效,但我不确定原因

我正在使用:

  • Mac 操作系统 10.8.5
  • 酿造 Python 2.7.5
  • 赛通 0.20.2

此代码主要取自 this video tutorialgit page ,但不幸的是,“开箱即用”对我不起作用。

此包装的目标是通过 Python 提供对普通 C 函数的访问,该函数接受整数或整数结构并将它们相加。

为此需要 5 个文件,如下所述:

  • adder.c:两个加法器函数的 C 代码:add(标量输入)和pair_add(结构输入)
  • adder.h: adder.c的头文件
  • c_adder.pxd:一个cython头文件——本质上告诉cython要注意主头文件的哪些部分
  • cy_adder.pyx:用于在python命名空间中定义这两个函数的cython代码
  • setup.py:执行cython代码编译的distutils文件

这个过程产生了两个文件

  • c_adder.c: 一个中间的cython c文件
  • c_adder.so: 可导入命名空间的python模块

输入文件如下:

加法器.c

#include <stdlib.h>
#include "adder.h"

int
pair_add(PAIR * ppair) {
return ppair->x + ppair->y;
}

int
add(int x, int y) {
return x + y;
}

加法器.h

typedef struct {
int x;
int y;
} PAIR;

int pair_add(PAIR * ppair);
int add(int, int);

c_adder.pxd

cdef extern from "adder.h":

ctypedef struct PAIR:
int x
int y


int add(int x, int y)
int pair_add(PAIR * ppair)

cy_adder.pyx

cimport c_adder

def add(x, y):
return c_adder.add(x, y)

def pair_add(x, y):
cdef c_adder.PAIR pair
pair.x = x
pair.y = y
return c_adder.pair_add(&pair)

setup.py

from setuptools import setup
from setuptools.extension import Extension
from Cython.Distutils import build_ext
from Cython.Build import cythonize


ext_modules = cythonize([Extension("cy_adder", ["cy_adder.pyx",'adder.c'])])


setup(
name = 'Hello world app',
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules
)

我能够通过运行成功创建一个 .so 文件

$ python setup.py build_ext --inplace

在与上述文件相同的目录中。然后可以将 cy_adder 加载到 python 解释器的命名空间中。


问题

在设置声明中,我将 adder.c 作为辅助模块包含在内。

如果我不这样做,我在导入 .so 文件时会收到以下错误:

ImportError: dlopen(./cy_adder.so, 2): Symbol not found: _add
Referenced from: ./cy_adder.so
Expected in: flat namespace
in ./cy_adder.so

我是否缺少一个步骤,这意味着我不需要显式传递 adder.c 以及我的设置命令?这样做是否会让自己面临一些潜在的不稳定因素?

最佳答案

adder.c 文件需要在某处被引用,以便它知道在哪里可以找到 add 的实现。如您所见,将 adder.c 列为附加源文件是可行的。使用外部(共享)C 库的更常见方法是将其编译为 libadder.so 并通过扩展声明中的 libraries 参数链接它。

对于这么简单的事情你也可以直接写

cdef extern from "adder.c":   # note the .c
int add(int x, int y)
...

或者将整个实现放在.h文件中。

关于python - 使用 Cython 传递 int 和 struct 包装 C 代码的最小示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24621889/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com