【发布时间】:2021-09-29 19:06:05
【问题描述】:
我正在编写一个 python + c 模块,我正在尝试将一个指针传递给我需要的某个结构。我正在使用 PyCapsule 封装指针,但在从中检索指针时遇到问题。 使用的 C 函数如下:
static PyObject *
spam_new (PyObject *self, PyObject *args)
{
unsigned int number;
struct spam *pointer;
if (!PyArg_ParseTuple(args, "I", &number)) {
return NULL;
}
state = (struct spam*) malloc(sizeof (struct spam));
if (state == NULL) {
return NULL;
}
spam_init(*pointer, number);
return PyCapsule_New((void*) pointer, "spam", &spam_destroy);
}
static PyObject *
spam_get (PyObject *self, PyObject *args)
{
PyObject *capsule, *result;
void *raw_pointer;
struct spam *pointer;
unsigned long long int number;
if (!PyArg_ParseTuple(args, "OK", capsule, &number)) {
return NULL;
}
printf("[DEBUG] Number: %llu\n", number);
printf("[DEBUG] Capsule pointer: %p\n", capsule);
raw_pointer = PyCapsule_GetPointer(capsule, "spam");
if (raw_pointer == NULL) {
return NULL;
}
pointer = (struct spam*) raw_pointer;
.
.
.
}
它们都用 METH_VARARGS 声明。 在 python 中,custom.new(1) 按预期返回一个胶囊,我将它存储在一个变量 c 中。 当调用 custom.get(c, 14) python 在 PyCapsule_GetPointer 函数调用时崩溃。两个打印显示相同 (14),这意味着 PyArg_ParseTuple 没有将胶囊作为参数传递。
出于安全原因,将指针作为 long 传递不是一种选择。
谢谢。
【问题讨论】:
-
对
PyArg_ParseTuple的调用不能修改capsule;在没有未初始化变量警告的情况下如何构建? -
我不知道,但它没有发出任何警告。它确实将胶囊修改为与另一个参数相同的值(指向内存地址 0x00...0014
-
它不会修改
capsule,因为你没有拿到它的地址。