Wie man einen Zeiger auf der C / C ++ - Seite in Python hat.
Etwas möchte eine C ++ - Klasse aus Python verwenden.
class Hello {
public:
void hello();
};
PyCapsule_New
Verwenden Sie PyCapsule_New
, um einen C / C ++ - Zeiger als PyObject *
zurückzugeben.
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);
}
Wenn Sie eine Funktion übergeben, die den Zeiger freigibt, gibt Python ihn frei. Wenn Sie den Speicher auf der C / C ++ - Seite verwalten und ihn nicht freigeben müssen, können Sie NULL anstelle von py_hello_free übergeben.
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
So kehren Sie zu einem C / C ++ - Zeiger PyCapsule_GetPointer
zurück:
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 oben...
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);
}
Die übliche setup.py
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'])
]
)
kompilieren
$ python3 setup.py build_ext --inplace
import cext02 #Erweiterung um C.
h = cext02.hello_alloc() # h = new Hello()Etwas wie
cext02.hello(h) # h->hello()Anruf
Verwenden Sie wie. (Wenn Sie es mit einer Python-Klasse umschließen, können Sie es natürlich wie ein Objekt verwenden.)
Um mit C-Erweiterungen zu beginnen, sollten Sie zuerst das Python-Kochbuch lesen. Python Cookbook 3rd Edition (O'Reilly)
Code: https://github.com/junkoda/python_c_ext/tree/master/02_pointer
Recommended Posts