gpt4 book ai didi

从 C 代码调用 Cython 函数引发段错误

转载 作者:太空狗 更新时间:2023-10-29 15:03:18 25 4
gpt4 key购买 nike

我正在尝试在 C 程序中调用 cython (cdef) 函数。当 cdef 函数包含 python 语句时,例如print(0.5) 或 python (def) 函数,调用 (cdef) 函数会引发段错误。

.pyx 文件:

# cython: language_level=3

cdef public double PI = 3.1415926

cdef public double get_e():
print("calling get_e()")
return 2.718281828

.c 文件:

#include "Python.h"
#include "transcendentals.h"
#include <math.h>
#include <stdio.h>

int main(int argc, char **argv) {
Py_Initialize();
PyInit_transcendentals();
printf("pi**e: %f\n", pow(PI, get_e()));
Py_Finalize();
return 0;
}

编译命令:

cython transcendentals.pyx

gcc -I. -I/usr/include/python3.5m -I/usr/include/python3.5m \
-Wno-unused-result -Wsign-compare \
-g -fstack-protector-strong -Wformat \
-Werror=format-security -DNDEBUG -g \
-fwrapv -O3 -Wall -Wstrict-prototypes \
-L/usr/lib/python3.5/config-3.5m-x86_64-linux-gnu \
-L/usr/lib transcendentals.c main.c \
-lpython3.5m -lpthread -ldl -lutil -lm -Xlinker \
-export-dynamic -Wl,-O1 -Wl,-Bsymbolic-functions

当我删除 get_e 函数的打印语句时,不会引发段错误。但是 PI 的值将为 0。

最佳答案

我猜您使用的是 Cython 0.29。 Since 0.29 , PEP-489已为 Python 版本 >=3.5 启用多阶段模块初始化。这意味着,正如您所经历的那样,使用 PyInit_XXX 已经不够了。

Cython's documentation建议使用inittab mechanism ,即您的 main-function 应该类似于:

#include "Python.h"
#include "transcendentals.h"
#include <math.h>
#include <stdio.h>

int main(int argc, char **argv) {
int status=PyImport_AppendInittab("transcendentals", PyInit_transcendentals);
if(status==-1){
return -1;//error
}
Py_Initialize();
PyObject *module = PyImport_ImportModule("transcendentals");

if(module==NULL){
Py_Finalize();
return -1;//error
}

printf("pi**e: %f\n", pow(PI, get_e()));
Py_Finalize();
return 0;
}

恢复旧行为的另一种可能性是定义宏 CYTHON_PEP489_MULTI_PHASE_INIT=0 并因此覆盖默认值,例如编译时在命令行上将 -DCYTHON_PEP489_MULTI_PHASE_INIT=0 传递给 gcc。

关于从 C 代码调用 Cython 函数引发段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55647555/

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