c - 从 C 代码调用 Cython 函数会引发分段错误
问题描述
我正在尝试在 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。从 0.29开始,PEP-489多阶段模块初始化已为 Python 版本 >=3.5 启用。这意味着,PyInit_XXX
正如您所体验的那样,使用已经不够了。
Cython 的文档建议使用inittab 机制,即您的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。
推荐阅读
- python-3.x - Django 本地主机重定向太多次
- rounding - Pentaho 数据集成在 16 位后四舍五入十进制值
- php - 为什么我在侧边栏上的活动链接不起作用?
- php - 如何使用所需的名称在 laravel 中上传文件
- functional-programming - F#(F sharp)解压函数解释
- reactjs - 在 ReactJs 中单击购物车图标后如何显示购物车模式
- docker - 如何从 Docker 容器内部访问在 WSL2 上运行的服务?
- c# - 跨会话保留 ASP.NET Core 3.1 身份外部登录身份验证 cookie
- xml - 逻辑应用 XML 管理
- jquery - 无法解析来自 SOAP 接口的 jquery 响应中的 XML