43 Stimmen

Abrufen von Daten aus ctypes Array in Numpy

Ich verwende ein Python (über ctypes ) gewickelte C-Bibliothek, um eine Reihe von Berechnungen durchzuführen. In verschiedenen Stadien der Ausführung möchte ich Daten in Python erhalten, und zwar numpy Arrays.

Das Wrapping, das ich verwende, bietet zwei verschiedene Rückgabemöglichkeiten für Array-Daten (was für mich von besonderem Interesse ist):

  • ctypes Array : Wenn ich es tue type(x) (wobei x die ctypes Array, erhalte ich eine <class 'module_name.wrapper_class_name.c_double_Array_12000'> im Gegenzug. Ich weiß, dass diese Daten eine Kopie der internen Daten aus der Dokumentation sind, und ich kann sie in eine numpy Array leicht:

    >>> np.ctypeslib.as_array(x)

Dies gibt eine 1D numpy Array der Daten.

  • ctype Zeiger auf Daten : In diesem Fall aus der Dokumentation der Bibliothek, verstehe ich, dass ich einen Zeiger auf die Daten gespeichert und verwendet direkt an die Bibliothek zu erhalten. Molke ich tun type(y) (wobei y der Zeiger ist) erhalte ich <class 'module_name.wrapper_class_name.LP_c_double'> . In diesem Fall bin ich immer noch in der Lage, die Daten wie folgt zu indizieren y[0][2] , aber ich war nur in der Lage, es in Numpy über eine super umständlich zu bekommen:

    >>> np.frombuffer(np.core.multiarray.int_asbuffer(
        ctypes.addressof(y.contents), array_length*np.dtype(float).itemsize))

Ich habe dies in einem alten numpy Mailingliste Thema von Travis Oliphant , aber nicht in der numpy Dokumentation. Wenn ich stattdessen wie oben beschrieben vorgehe, erhalte ich das folgende Ergebnis:

>>> np.ctypeslib.as_array(y)
...
...  BUNCH OF STACK INFORMATION
...
AttributeError: 'LP_c_double' object has no attribute '__array_interface__'

Ist das np.frombuffer die beste oder einzige Möglichkeit, dies zu tun? Ich bin offen für andere Vorschläge, aber ich würde gerne noch numpy da ich eine Menge anderer Nachbearbeitungscodes habe, die sich auf numpy Funktionalität, die ich mit diesen Daten verwenden möchte .

0 Stimmen

Haben Sie die Kontrolle über die C-Lib? Können Sie die API der Bibliothek ändern?

0 Stimmen

Ja - ich habe die Quelle. Ich bin mir nicht sicher, welchen Weg ich einschlagen soll, da der Pointer-Ansatz es Python ermöglicht, direkt auf die Daten zuzugreifen, was in einigen Fällen ein Vorteil sein könnte. In meinem Fall wäre es jedoch von Vorteil, wenn alles als Zeiger ausgegeben würde. ctype Array. Irgendwelche Empfehlungen?

2 Stimmen

Ich würde vorschlagen, dass die Bibliothek ein (NumPy-) Array verwendet, das Sie in Python zuweisen und an die Bibliothek weitergeben. Auf diese Weise können Sie auf denselben Speicher zugreifen, müssen sich aber nicht mit umständlichen Konvertierungen herumschlagen. Sie haben bereits ein NumPy-Array, und die Übergabe an eine Bibliothek wird gut unterstützt durch die Verwendung von numpy.ctypeslib.ndpointer als Argumenttyp für die ctypes-Verschalung Ihrer Funktion. (Wenn das nicht klar ist, fragen Sie einfach...)

0voto

Ilya Prokin Punkte 606

Wenn Sie mit der Erstellung von Arrays in Python zurechtkommen, funktioniert das folgende Beispiel mit einem 2D-Array in Python 3:

import numpy as np
import ctypes

OutType = (ctypes.c_float * 4) * 6
out = OutType()
YourCfunction = ctypes.CDLL('./yourlib.so').voidreturningfunctionwithweirdname
YourCfunction.argtypes = [ctypes.POINTER(ctypes.c_float)]*3, ctypes.POINTER(ctypes.c_float)]*5, OutType]
YourCfunction(input1, input2, out)
out = np.array(out) # convert it to numpy

print(out)

die Versionen von numpy und ctypes sind 1.11.1 und 1.1.0

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X