在 C 和 Python 之间传递的 C 指针(使用胶囊)为空
A C pointer passed between C and Python (using capsule) is empty
我正在为我开发的一些 C 函数创建一个 python 扩展。
该代码使用了我们不需要从 python 代码中分析的复杂结构,因此我们使用指针胶囊将结构从一个函数传递到另一个函数。
这是我在 C 中创建的 python 扩展的简化(这里我只使用双精度而不是我们的结构):
#include "Python.h"
static PyObject *example2 (PyObject *dummy, PyObject *args)
{
PyObject *pymodel=NULL;
if (!PyArg_ParseTuple(args, "O", &pymodel))
return NULL;
double *numero;
if (!(numero = (double*) PyCapsule_GetPointer(pymodel, "DOUBLE"))) {
return NULL;
}
printf("Pointer %x and value %f\n",numero,*numero);
return Py_BuildValue("");
}
static PyObject* example (PyObject *dummy, PyObject *args)
{
double *numero;
double valnum = 6.0;
numero = &valnum;
printf("Pointer %x and value %f\n",numero,*numero);
PyObject * ret = PyCapsule_New(numero, "DOUBLE", NULL);
return ret;
}
/* Module method table */
static PyMethodDef LIBIRWLSMethods[] = {
{"example", example, METH_VARARGS, "descript of example"},
{"example2", example2, METH_VARARGS, "prediction using a trained model"},
{ NULL, NULL, 0, NULL}
};
/* module initialization */
PyMODINIT_FUNC initLIBIRWLS(void)
{
(void) Py_InitModule("LIBIRWLS", LIBIRWLSMethods);
}
使用 setup.py 文件安装此扩展后,我们调用 python:
中的函数
import LIBIRWLS
myCapsule = LIBIRWLS.example()
LIBIRWLS.example2(myCalsule)
这是 运行 python 代码后的标准输出:
Pointer b9c27b58 and value 6.000000
Pointer b9c27b58 and value 0.000000
指针地址已正确传递,但它丢失了值,我们不知道原因。
您正在尝试传递指向堆栈上某个值的指针。请参阅 this question 了解为什么这是个坏主意。要传递指针,您需要从堆中分配内存:
static PyObject *example2 (PyObject *dummy, PyObject *args)
{
PyObject *pymodel = NULL;
if (!PyArg_ParseTuple(args, "O", &pymodel))
return NULL;
double *numero;
if (!(numero = (double*) PyCapsule_GetPointer(pymodel, "DOUBLE")))
return NULL;
printf("Pointer %p and value %f\n", numero, *numero);
return Py_BuildValue("");
}
static PyObject* example (PyObject *dummy, PyObject *args)
{
double *numero = (double *) PyMem_Malloc(sizeof(double *));
if (NULL == numero)
return NULL;
*numero = 6.0;
printf("Pointer %p and value %f\n", numero, *numero);
PyObject * ret = PyCapsule_New(numero, "DOUBLE", NULL);
return ret;
}
输出
Pointer 0x7f9103d173f0 and value 6.000000
Pointer 0x7f9103d173f0 and value 6.000000
我正在为我开发的一些 C 函数创建一个 python 扩展。
该代码使用了我们不需要从 python 代码中分析的复杂结构,因此我们使用指针胶囊将结构从一个函数传递到另一个函数。
这是我在 C 中创建的 python 扩展的简化(这里我只使用双精度而不是我们的结构):
#include "Python.h"
static PyObject *example2 (PyObject *dummy, PyObject *args)
{
PyObject *pymodel=NULL;
if (!PyArg_ParseTuple(args, "O", &pymodel))
return NULL;
double *numero;
if (!(numero = (double*) PyCapsule_GetPointer(pymodel, "DOUBLE"))) {
return NULL;
}
printf("Pointer %x and value %f\n",numero,*numero);
return Py_BuildValue("");
}
static PyObject* example (PyObject *dummy, PyObject *args)
{
double *numero;
double valnum = 6.0;
numero = &valnum;
printf("Pointer %x and value %f\n",numero,*numero);
PyObject * ret = PyCapsule_New(numero, "DOUBLE", NULL);
return ret;
}
/* Module method table */
static PyMethodDef LIBIRWLSMethods[] = {
{"example", example, METH_VARARGS, "descript of example"},
{"example2", example2, METH_VARARGS, "prediction using a trained model"},
{ NULL, NULL, 0, NULL}
};
/* module initialization */
PyMODINIT_FUNC initLIBIRWLS(void)
{
(void) Py_InitModule("LIBIRWLS", LIBIRWLSMethods);
}
使用 setup.py 文件安装此扩展后,我们调用 python:
中的函数import LIBIRWLS
myCapsule = LIBIRWLS.example()
LIBIRWLS.example2(myCalsule)
这是 运行 python 代码后的标准输出:
Pointer b9c27b58 and value 6.000000
Pointer b9c27b58 and value 0.000000
指针地址已正确传递,但它丢失了值,我们不知道原因。
您正在尝试传递指向堆栈上某个值的指针。请参阅 this question 了解为什么这是个坏主意。要传递指针,您需要从堆中分配内存:
static PyObject *example2 (PyObject *dummy, PyObject *args)
{
PyObject *pymodel = NULL;
if (!PyArg_ParseTuple(args, "O", &pymodel))
return NULL;
double *numero;
if (!(numero = (double*) PyCapsule_GetPointer(pymodel, "DOUBLE")))
return NULL;
printf("Pointer %p and value %f\n", numero, *numero);
return Py_BuildValue("");
}
static PyObject* example (PyObject *dummy, PyObject *args)
{
double *numero = (double *) PyMem_Malloc(sizeof(double *));
if (NULL == numero)
return NULL;
*numero = 6.0;
printf("Pointer %p and value %f\n", numero, *numero);
PyObject * ret = PyCapsule_New(numero, "DOUBLE", NULL);
return ret;
}
输出
Pointer 0x7f9103d173f0 and value 6.000000
Pointer 0x7f9103d173f0 and value 6.000000