numpy-array von pointer

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
HerrHagen
User
Beiträge: 430
Registriert: Freitag 6. Juni 2008, 19:07

Hallo zusammen!

Ich habe folgendes Problem: Ich habe ein Kamerasystem welches Daten an meinen Rechner sendet.
Zur Ansteuerung der Kamera und Auslesen der Daten gibt es eine API, jedoch leider nur für C und C++.
Um das Problem zu lösen dachte ich mir, dass ich eine DLL, die die entsprechende Funktionalität bereitstellt,
erstelle und diese dann mit ctypes ansteuere.

Das ganze scheitert bei mir an einer Sache: Wie kann ich ein Array an Python übergeben und die Daten auch tatsächlich auslesen,
ohne dass ich vorher ein Array von Python aus übergebe, welches dann überschrieben wird? D.h. wie greif ich auf die Daten von
Python aus zu wenn ich nur nen Pointer übergeben kann? Gibt es vielleicht sogar eine Möglichkeit
das ganze direkt in ein Numpy-Array zu bringen (so eine Art numpy.from_memory(adress, ...))?

MFG Herr Hagen
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Hoi,

wieso nur Pointer übergeben? Üblicherweise sind das doch Funktionen vom Typ "static PyObject *"?

Hier gibt es Beispiele. (Insbesondere ganz unten auf der Seite.)

Gruß,
Christian
Benutzeravatar
HerrHagen
User
Beiträge: 430
Registriert: Freitag 6. Juni 2008, 19:07

Ich wollte eigentlich verhindern ein Extension-Modul zu erstellen... da ich davon keine Ahnung hab. Numpy hat ja auch ne API, wo sowas möglich wäre.
Ich denke jedoch es müsste auch einfacher möglich sein. Ist ja eigentlich was ganz Grundlegendes, was auch mit ein paar Zeilen möglich sein müsste.
Außerdem gibt es schon eine fertige .dll auf die ich gern zurückgreifen würde, - nachträglich in die python.h einfügen und und C-Array in Python-Objekt umwandeln geht da ja nich.
Es gibt ja bei numpy eine Funktion numpy.frombuffer. Kann man nicht vielleicht einen Puffer von dem Datenbereich, startend mit Pointer und mit der Länge x erstellen und ihn so in so in numpy nutzen?

MFG HerrHagen
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Auf der Mailingliste wirst Du da sicher kompetente Antwort bekommen. Aber wenn ich noch ein paar Anmerkungen machen darf:
Ist ja eigentlich was ganz Grundlegendes, was auch mit ein paar Zeilen möglich sein müsste.
In einem Extensionmodul ist die Konvertierung in ein ndarray auch in einer Zeile möglich - siehe Beispiel.
Außerdem gibt es schon eine fertige .dll auf die ich gern zurückgreifen würde, - nachträglich in die python.h einfügen und und C-Array in Python-Objekt umwandeln geht da ja nich.
Ah, so, die gibt es also schon. Und die gibt ein C-array (int* oder float* oder double*) zurück? Dann kann man doch auch in Python die Konvertierung in ein ndarray machen (

Code: Alles auswählen

x = numpy.array(list-object)
) nachdem es mit ctypes gewonnen wurde.

Gruß,
Christian
Benutzeravatar
HerrHagen
User
Beiträge: 430
Registriert: Freitag 6. Juni 2008, 19:07

Ah, so, die gibt es also schon.
Ja; habe entdeckt, dass es nich nur ein paar lib's und header gibt die man linken kann, sondern auch ne fertige *.dll.
Und die gibt ein C-array (int* oder float* oder double*) zurück?
Es ist ein Array mit abwechselnd 1500 uint8 und 1500 uint16.
Dann kann man doch auch in Python die Konvertierung in ein ndarray machen nachdem es mit ctypes gewonnen wurde.
Wie krieg ich eigentlich eine Liste aus ctypes raus?

Ich weiß jedoch nicht ob das überhaupt sinnvoll ist. Ich wollte das Ganze möglichst performant gestalten. Für das Auslesen von 7 MByte in ein numpy-Array sind nur ca. 0.1s Zeit - umso schneller umso besser. Deswegen wollt ich ungern erst ne Liste mit 2Mio+ Elementen machen.

Unabhängig davon habe ich einfach mal eine andere Variante gemacht und soeben mein erstes Extension-"Model" :lol: erstellt.
Ich hab mal mein Vorgehen angefügt.
Hier der C-Teil:

Code: Alles auswählen

#include <Python.h>
static PyObject *mem2buffer_buffer_from_memory(PyObject *self, PyObject *args);
static PyMethodDef mem2bufferMethods[] = 
    { 
		{"buffer_from_memory", mem2buffer_buffer_from_memory, METH_VARARGS, "Returns buffer."}, 
		{NULL, NULL, 0, NULL} 
    };
PyMODINIT_FUNC initmem2buffer(void) 
    { 
    Py_InitModule("mem2buffer", mem2bufferMethods); 
    }

static PyObject *mem2buffer_buffer_from_memory(PyObject *self, PyObject *args) 
    { 
	static char feld[] = {1,2,3,4,9};
    PyObject *ergebnis;

	ergebnis = PyBuffer_FromMemory(feld, 5);
//    ergebnis = PyString_FromStringAndSize(feld, 5); 
	return ergebnis; 
    }
Wenn man nun folgenden code mit "python setup.py build -c mingw32" (Windows mit MinGW) aufruft wird das Modul erstellt.

Code: Alles auswählen

from distutils.core import setup, Extension

modul = Extension("mem2buffer", sources=["mem2buffer.c"]) 
setup( 
     name = "mem2buffer", 
     version = "1.0", 
     description = "Mem 2 buffer.", 
     ext_modules = [modul] 
     )
Nun kann ich mit

Code: Alles auswählen

import mem2buffer
import numpy

print numpy.frombuffer(mem2buffer.buffer_from_memory(), 'b')

# [1 2 3 4 9]
aus den ursprünglichen Daten ein Numpy-Array erstellen.
Das ganze wäre sicherlich noch besser, wenn man direkt ein Numpy-Array erstellt. Durch den Code den du gelinkt hast, blick ich nur noch nicht ganz durch.
Wenn jemand noch ne bessere Variante (vielleicht ohne den Umweg über Extension-Modul) hat, bitte posten.

MFG HerrHagen[/code]
Antworten