Comment avoir un pointeur côté C / C ++ en Python.
Quelque chose veut utiliser une classe C ++ de Python.
class Hello {
public:
void hello();
};
PyCapsule_New
Utilisez PyCapsule_New
pour renvoyer un pointeur C / C ++ comme PyObject *
.
static void py_hello_free(PyObject *obj);
static PyObject* py_hello_alloc(PyObject *self, PyObject *args)
{
// Allocate a new C++ pointer h as a Python object "_Hello"
Hello* const h= new Hello();
return PyCapsule_New(h, "_Hello", py_hello_free);
}
Si vous passez une fonction qui libère le pointeur, Python le publiera. Si vous gérez la mémoire côté C / C ++ et n'avez pas besoin de la libérer, vous pouvez passer NULL au lieu de py_hello_free.
void py_hello_free(PyObject *obj)
{
// Destructor function for _Hello pointer, called automatically from Python
Hello* const h= (Hello*) PyCapsule_GetPointer(obj, "_Hello");
delete h;
}
PyCapsule_GetPointer
Pour revenir à un pointeur C / C ++ PyCapsule_GetPointer
:
PyObject* py_hello(PyObject *self, PyObject *args)
{
// Use _Hello pointer from Python
PyObject* py_obj;
if(!PyArg_ParseTuple(args, "O", &py_obj))
return NULL;
Hello* h= (Hello*) PyCapsule_GetPointer(py_obj, "_Hello");
if(h == 0) return NULL;
h->hello();
Py_RETURN_NONE;
}
#include <cstdio>
#include "Python.h"
// ...Code ci-dessus...
static PyMethodDef methods[] = {
{"hello_alloc", py_hello_alloc, METH_VARARGS, "allocate a Hello object"},
{"hello", py_hello, METH_VARARGS, "call hello() method"},
{NULL, NULL, 0, NULL}
};
static struct PyModuleDef module = {
PyModuleDef_HEAD_INIT,
"cext02", // name of this module
"Use C/C++ pointer", // Doc String
-1,
methods
};
PyMODINIT_FUNC
PyInit_cext02(void) {
return PyModule_Create(&module);
}
Le setup.py
habituel
from distutils.core import setup, Extension
setup(name='cext02',
version='0.0.1',
description='c_ext02 pointer',
author='Jun Koda',
url='https://github.com/junkoda/python_c_ext',
ext_modules=[
Extension('cext02', ['cext02.cpp'])
]
)
compiler
$ python3 setup.py build_ext --inplace
import cext02 #Extension par C
h = cext02.hello_alloc() # h = new Hello()Quelque chose comme
cext02.hello(h) # h->hello()Appel
Utilisez comme. (Bien sûr, si vous l'enveloppez avec une classe Python, vous pouvez l'utiliser comme un objet.)
Pour commencer avec les extensions C, c'est une bonne idée de lire d'abord le livre de recettes Python. Python Cookbook 3rd Edition (O'Reilly)
Code: https://github.com/junkoda/python_c_ext/tree/master/02_pointer
Recommended Posts