python - C python扩展中的分段错误
问题描述
我正在为 python3.7 编写一个 C 扩展模块。我有一个简单的结构作为 PyObject:
typedef struct {
PyObject_HEAD
double attacker;
double victim;
double game_hardness;
int inflation;
} RatingSystem;
和初始化器:
static int
RatingSystem_init(RatingSystem *self, PyObject *args, PyObject *kwargs) {
double kek;
static char *kwargs_list[] = {"attacker", "victim", "game_hardness", "inflation"};
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$dddi", kwargs_list,
&self->attacker, &self->victim,
&self->game_hardness, &self->inflation)) {
return -1;
}
printf("Success\n");
return 0;
}
如果我在 python 3.7.3 下的 Mac OS 上运行它,一切正常,但如果我切换到 alpine 3.10 python docker image (python:3.7-alpine),在以下初始化:
import rating_system
rs = rating_system.RatingSystem(attacker=1000.0, victim=1000.0, game_hardness=1300.0, inflation=1)
我明白了Segmentation fault
。在 gdb 下运行显示如下:
Program received signal SIGSEGV, Segmentation fault.
vgetargskeywords (args=0x7f87284f0050, kwargs=0x7f87284e0a00, format=<optimized out>, format@entry=0x7f8728301000 "|$dddi", kwlist=kwlist@entry=0x7f8728303020 <kwargs_list>, p_va=p_va@entry=0x7ffeeee6e4e0,
flags=flags@entry=2) at Python/getargs.c:1640
1640 Python/getargs.c: No such file or directory.
如果我inflation
从 init 中删除,代码也可以工作,即这段代码:
static int
RatingSystem_init(RatingSystem *self, PyObject *args, PyObject *kwargs) {
static char *kwargs_list[] = {"attacker", "victim", "game_hardness"};
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$ddd", kwargs_list,
&self->attacker, &self->victim,
&self->game_hardness)) {
return -1;
}
printf("Success\n");
return 0;
}
作品。
我的初始化有什么问题吗?我尝试为最后一个参数使用不同的类型,但没有运气。
解决方案
根据docs,参数需要一个PyArg_ParseTupleAndKeywords
以keywords
NULL 结尾的关键字参数名称数组。
添加一个额外的NULL
元素到你的kwargs_list
:
static char *kwargs_list[] = {"attacker", "victim", "game_hardness", NULL};
推荐阅读
- flutter - 在综合浏览量中:- 滑动时有时会调用 2-3 次 itemBuilder
- wordpress - 如何在 WordPress 中插入 Bootstrap 4 菜单?
- javascript - 无法将数据从 asp.net 动态传递到 javascript 函数?
- swift - 从 Swift 5 FileManager 特定目标 URL 读取数据
- javascript - 如何使用超级代理从 GET/POST 响应消息中提取值
- flutter - 如何将自己的样式添加到 gmap [google_map_flutter 插件]
- vim - VIM:如何获取当前函数名
- c# - 从一个线程读取变量并从另一个线程写入的正确方法?
- firebase - Firebase 数据库规则设置为所有者只读
- prolog - 谓词与函数 PROLOG