Zeigen Sie C / C ++ - Daten in Python als np.array an.
struct Particle {
float x[3], v[3];
};
vector<Particle> v;
Angenommen, Daten wie "Partikel *" befinden sich auf der C / C ++ - Seite.
numpy.array from C/C++
Fügen Sie zuerst numpy / arrayobject.h
ein und initialisieren Sie es. Dies scheint statische Variablen zu initialisieren, und wenn Sie mehr als einen Quellcode haben, müssen Sie im gesamten Quellcode, der numpy verwendet, "import_array ()" aufrufen. Andernfalls wird ein Segmentierungsfehler angezeigt.
#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include "numpy/arrayobject.h"
PyMODINIT_FUNC
PyInit_cext07(void) {
import_array();
return PyModule_Create(&module);
}
Setzen Sie include_dirs
in setup.py
, um den NumPy-Header zu lesen.
import numpy as np
from distutils.core import setup, Extension
setup(name='cext07',
version='0.0.1',
description='c_ext07 read data as np.array',
author='Jun Koda',
url='https://github.com/junkoda/python_c_ext',
ext_modules=[
Extension('cext07', ['cext07.c'],
include_dirs = [np.get_include()]),
],
)
Eine Funktion, die einen Zeiger auf "vector
static void py_particles_free(PyObject *obj);
static PyObject* py_particles_alloc(PyObject *self, PyObject *args)
{
// Allocate a new C++ pointer as a Python object "_Particles"
vector<Particle>* const p= new vector<Particle>();
p->resize(10); //Angenommen, die Daten enthalten 10 Partikel
return PyCapsule_New(p, "_Particles", py_particles_free);
}
void py_particles_free(PyObject *obj)
{
// Destructor function for _Particles pointer, called automatically from Python
vector<Particle>* const p=
(vector<Particle>*) PyCapsule_GetPointer(obj, "_Particles");
delete p;
}
Eine Funktion, die vector <Picle>
als np.array
übergibt:
PyObject* py_as_array(PyObject *self, PyObject *args)
{
PyObject* py_particles;
if(!PyArg_ParseTuple(args, "O", &py_particles))
return NULL;
// Get vector<Particle>* pointer back from _Particles
vector<Particle>* const p=
(vector<Particle>*) PyCapsule_GetPointer(py_particles, "_Particles");
if(!p) return NULL;
int nd=2; //Zweidimensionales Array mit Zeilen und Spalten
int ncol= sizeof(Particle)/sizeof(float); // ncol=6 x[3], v[3]6 Reihen
npy_intp dims[]= {(npy_intp) p->size(), ncol};
return PyArray_SimpleNewFromData(nd, dims, NPY_FLOAT, &(p->front()));
}
Übliche C / C ++ - Erweiterungsfunktionen
static PyMethodDef methods[] = {
{"_particles_alloc", py_particles_alloc, METH_VARARGS, "new Particles"},
{"_as_array", py_as_array, METH_VARARGS, "vector<Particle> as an array"},
{NULL, NULL, 0, NULL}
};
static struct PyModuleDef module = {
PyModuleDef_HEAD_INIT,
"cext07", // name of this module
"Use vector<Particle>", // Doc String
-1,
methods
};
import numpy as np
import cext07
class Particles:
def __init__(self):
self._p= cext07._particles_alloc() # _Partikelzeiger
def __repr__(self):
return cext07._as_array(self._p).__repr__()
def __getitem__(self, index):
return cext07._as_array(self._p)[index]
def asarray(self):
return cext07._as_array(self._p)
#etc
import cext07
p = Particles()
p # __repr__Sieht Array von
p[0] # __getitem__;Erstes Teilchen
p[2:5,2] #Scheibe ist auch np.Array behandelt es
p[:,0] # x[0]
p[:,4] # v[1]
p[:] #Alle Daten
In diesem Beispiel brauchten wir keine Python-Klassen, nur die as_array-Funktion. Ich werde es später vereinfachen.
Den vollständigen Code finden Sie unter GitHub.
Recommended Posts