So geben Sie ein Array von einer C++-Funktion mit ctypes an Python zurück
Lesezeit: 3 Minuten
Ich verwende ctypes, um eine C++-Funktion in Python zu implementieren. Die C++-Funktion sollte einen Zeiger auf ein Array zurückgeben. Leider habe ich nicht herausgefunden, wie ich in Python auf das Array zugreifen kann. Ich habe numpy.frombuffer ausprobiert, aber das war nicht erfolgreich. Es hat nur ein Array willkürlicher Zahlen zurückgegeben. Offensichtlich habe ich es nicht richtig verwendet. Hier ist ein einfaches Beispiel mit einem Array der Größe 10:
Inhalt der function.cpp:
extern "C" int* function(){
int* information = new int[10];
for(int k=0;k<10;k++){
information[k] = k;
}
return information;
}
Haben Sie Vorschläge, was ich tun muss, um auf die Array-Werte in Python zuzugreifen?
Natürlich habe ich vergessen, einige spezifische ctypes-Funktionen wie c_double und POINTER zu importieren. Ich habe nur vergessen, sie hier hinzuzufügen.
– Dolby
15. Februar 13 um 2:38 Uhr
Hui Zheng
Ihr Python-Code wird nach einigen geringfügigen Änderungen funktionieren:
import ctypes
f = ctypes.CDLL('./library.so').function
f.restype = ctypes.POINTER(ctypes.c_int * 10)
print [i for i in f().contents] # output: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Grundsätzlich gibt es zwei Änderungen:
numpy-bezogenen Code entfernen und ctypes.cast anrufen, da wir sie nicht brauchen.
Geben Sie den Rückgabetyp an ctypes.POINTER(ctypes.c_int * 10).
Standardmäßig wird davon ausgegangen, dass Fremdfunktionen den Typ C int zurückgeben, daher müssen wir ihn in den gewünschten Zeigertyp ändern.
Übrigens, Rückgabe von a newed-Array von C-Code zu Python-Code scheint unangemessen. Wer und wann gibt den Speicher frei? Es ist besser, Arrays in Python-Code zu erstellen und sie an C-Code zu übergeben. Auf diese Weise ist klar, dass der Python-Code besitzt die Arrays und übernimmt die Verantwortung für die Schaffung und Rückgewinnung ihrer Räume.
Können Sie darauf hinweisen, wie wir ein solches Array in Python erstellen und seinen Zeiger an C übergeben würden?
– Shahensha
21. Juli 15 um 5:19 Uhr
@Shahensha Was ich für int/float-Arrays mache, ist die Verwendung von numpy-Arrays und der eingebetteten ctypes-Schnittstelle (data_as)
– Nachteil
26. April 16 um 14:19 Uhr
Ein bisschen Nekromantie hier … Wie würden Sie die Erinnerung löschen, wenn Sie damit fertig sind?
– XapaJIaMnu
5. Januar 17 um 18:35 Uhr
Danika
function.cpp gibt ein int-Array zurück, während wrapper.py versucht, sie als Doubles zu interpretieren. Veränderung ArrayType zu ctypes.c_int * 10 und es sollte funktionieren.
Es ist wahrscheinlich einfacher, es einfach zu verwenden np.ctypeslib anstatt frombuffer du selber. Das sollte in etwa so aussehen
import ctypes
from numpy.ctypeslib import ndpointer
lib = ctypes.CDLL('./library.so')
lib.function.restype = ndpointer(dtype=ctypes.c_int, shape=(10,))
res = lib.function()
Ich habe auch c_int importiert und c_double ersetzt, aber Python gibt jetzt ein Array von nur 5 Elementen aus und die Werte sind immer noch falsch. Das ist seltsam.
– Dolby
15. Februar 13 um 3:10 Uhr
Ausgezeichnet! Vielen Dank! Es funktioniert jetzt. Python gibt mir nur die Warnung “[…] RuntimeWarning: Ungültiger PEP 3118-Formatstring: ‘
– Dolby
15. Februar 13 um 3:28 Uhr
Ein bisschen Nekromantie hier … Wie würden Sie die Erinnerung löschen, wenn Sie damit fertig sind?
– XapaJIaMnu
5. Januar 17 um 18:34 Uhr
@XapaJlaMnu Ihre Bibliothek sollte eine entsprechende haben extern C -Funktion aufrufen, um den Speicher freizugeben, der intern C++ verwendet delete wenn es mit belegt wurde new. ctypes verwendet C-Schnittstellen, und da C keine hat delete, ctypes auch nicht.
– Danika
5. Januar 17 um 18:39 Uhr
Wie in der anderen Antwort vorgeschlagen, ist es nach Möglichkeit normalerweise besser, den Speicher mit numpy zuzuweisen und ihn zum Auffüllen an eine C-Funktion zu übergeben.
– Danika
5. Januar 17 um 18:41 Uhr
.
5088300cookie-checkSo geben Sie ein Array von einer C++-Funktion mit ctypes an Python zurückyes
Natürlich habe ich vergessen, einige spezifische ctypes-Funktionen wie c_double und POINTER zu importieren. Ich habe nur vergessen, sie hier hinzuzufügen.
– Dolby
15. Februar 13 um 2:38 Uhr