gpt4 book ai didi

python - Cython:从 C 程序调用 Python 代码

转载 作者:太空狗 更新时间:2023-10-29 15:38:39 24 4
gpt4 key购买 nike

我正在尝试制作一个 Cython 包装器,以便我可以从 C 调用 Python 代码。我在导入时遇到问题,因为我希望包装器与原始代码分开。

以下代码在调用导入函数时以segfault 结束。如果代码作为 python 模块编写并通过 import 导入,程序会提示 name ... 未定义。当所有内容都在一个文件中并且不涉及导入时,问题不会自行显现(实际上,Cython 生成的代码在导入时会失败)。当从其他 python 脚本导入 libcimpy.pyx(编译为 .so 或实时)时,代码也能正常工作

我准备了一个最小的例子。这与实际代码相去甚远,但涵盖了原理。

cimpPy.pyx:示例 python 代码(转换为 Cython)

cdef sum(a, b):
return a + b

cimpPy.pxd

cdef sum(a, b)

libcimpy.pyx(粘合 Cython 代码)

cimport cimpPy

cdef public int cSum(int a, int b):
return cimpPy.sum(a, b)

ci.c(我们要从中调用 cimpPy 的 c 代码)

#include <stdio.h>
#include <stdlib.h>
#include <Python.h>
#include "libcimp.h"

int main(int argc, char **argv) {
Py_Initialize();
initlibcimp();
int a = 2;
int b = 3;
int c = cSum(a, b);
printf("sum of %d and %d is %d\n", a, b, c);
Py_Finalize();
return 0;
}

生成文件

EXECUTABLE = ci

OBJS = ci.o

CC = gcc
CFLAGS = -g -I/usr/include/python2.7 -I$(shell pwd)

LINKER = g++
LDFLAGS = -L$(shell pwd) $(shell python-config --ldflags) -lcimp
.PHONY: clean cython

all: cython $(EXECUTABLE)

cython:
python setup.py build_ext --inplace

.c.o:
$(CC) $(CFLAGS) -c $<

$(EXECUTABLE) : $(OBJS)
$(LINKER) -o $(EXECUTABLE) $(OBJS) $(LDFLAGS)

clean:
rm -rf *.o *.so libcimp.c libcimp.h core build $(EXECUTABLE)

设置.py

from distutils.core import setup, Extension
from Cython.Build import cythonize
from Cython.Distutils import build_ext

extensions = [
Extension("libcimp", ["libcimp.pyx"])
]

setup(
name = "CIMP",
cmdclass = {"build_ext": build_ext},
ext_modules = cythonize(extensions)
)

我打算实现的是能够将 Python 代码插入更大的 C 系统。假设用户将能够自己编写 Python。 C代码是一个模拟引擎,可以在环境中对代理进行操作。这个想法是可以在 python 中指定代理和环境的行为,并在必要时传递给引擎进行评估。最好的类比是 map reduce 系统,其中 Python 脚本是映射器。从这个意义上说,我想从 C 调用 Python,而不是相反。

将所有内容都转换为 Cython,虽然引人注目将是一项艰巨的任务。

这是正确的方法吗?为什么 import 只能在 python 解释器下工作,而不是在外部嵌入时工作?任何建议和引用文章或文档表示赞赏。

最佳答案

在这段代码中,initlibcimp() 实际上失败了,但您不会立即看到它,因为错误是通过设置 python 异常来报告的。我不是 100% 确定这是执行此操作的正确方法,但我可以通过在该调用下方添加以下代码来查看错误:

if (PyErr_Occurred())
{
PyErr_Print();
exit(-1);
}

然后,程序会输出:

Traceback (most recent call last):
File "libcimpy.pyx", line 1, in init libcimpy (libcimpy.c:814)
cimport cimpPy
ImportError: No module named cimpPy

cimpPy 模块尚未定义的原因是您需要在调用 initlibcimp 之前调用 initcimpPy() .

关于python - Cython:从 C 程序调用 Python 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20962278/

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