Hallo leute,
ich Programmier im Moment eine API-Schnittstelle.
Eine Funktion dieser Schnittstelle will als Übergabeparameter unteranderem einen Pointer auf ein array.
Wie kann ich das realisieren? Kann mir da jemand weiter helfen?
Schonmal danke für eure Antworten
Liebe Grüße
C-Funktion mit pointer übergabe
-
BlackJack
@gosi: Und wo ist jetzt das Problem? Was hast Du denn bisher versucht? Das Tutorial für `ctypes` in der Dokumentation hat sowohl einen Abschnitt über das Aufrufen mit Zeigern, als auch einen über Arrays.
-
BlackJack
@Sirius: Ich würde es mit `ctypes` alleine machen, zumindest wenn tatsächlich 16-Bit-unsigned gefordert ist und nicht was auch immer `short` beim C-Compiler ist/war mit dem Python übersetzt wurde. Ist vielleicht übertrieben, aber es ist halt sicherer.
-
Leonidas
- Python-Forum Veteran
- Beiträge: 16025
- Registriert: Freitag 20. Juni 2003, 16:30
- Kontaktdaten:
Finde die offizielle ctypes-Dokumentation recht gelungen. Natürlich, man muss C kennen, aber wenn man das nicht kann wird man so oder so nicht weiter kommen.gosi hat geschrieben:Wo finde ich denn eine vernünftige dokumentation über ctypes?
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Guten morgen.
erstmal danke für die Antworten.
ich habe mir nun mal die Doku angeschaut.
mit dem code :
kann man ja nun ein array erstellen.
Ich hab nun das problem das ich eine .wav Datei auslese und die Daten zunächst in eine Liste speicher mit folgendem Code:
Nun muss ich stückchen weise die daten daraus in ein c-array schieben, welches dann die c-Funktion übergeben bekommt.
Mir fällt dazu grad nicht ein wie ich das realisieren kann. Kann mir da nun jemand weiterhelfen?
erstmal danke für die Antworten.
ich habe mir nun mal die Doku angeschaut.
mit dem code :
Code: Alles auswählen
>>> from ctypes import *
>>> TenIntegers = c_int * 10
>>> ii = TenIntegers(1, 2, 3, 4, 5, 6, 7, 8,9,10)Ich hab nun das problem das ich eine .wav Datei auslese und die Daten zunächst in eine Liste speicher mit folgendem Code:
Code: Alles auswählen
while iCounter < iFrames:
i = 1
while i <= iChannels:
frame = fObj.readframes(0.4)
sample = int(frame.encode("hex"),16)
sSampleBlock.append(sample)
i +=1
iCounter +=1
Mir fällt dazu grad nicht ein wie ich das realisieren kann. Kann mir da nun jemand weiterhelfen?
-
BlackJack
@gosi: Ich würde als erstes mal ein Python-Grundlagentutorial empfehlen. Da lernst Du dann etwas über ``for``-Schleifen.
Und dann den Style Guide for Python Code zur Namensschreibweise. Und werd bitte diese hässliche ungarische Notation los.
Bei `fObj` handelt es sich um ein `wave.Wave_read`-Objekt vermute ich mal. Das man die `readframes()`-Methode mit einer Gleitkommazahl < 1 aufrufen kann ist, hm, überraschend. Das würde ich sein lassen, oder zumindest kommentieren was dieser Hack macht und warum gerade 0.4 als Wert.
Die Umkodierung von `sample` ist umständlich. Falls das ein Byte sein sollte gibt es `ord()`, ansonsten das `struct`-Modul. Oder das `array`-Modul. Oder halt gleich `ctypes` um eine Zeichenkette mit entsprechend vielen Bytes direkt in das Array zu kopieren. Das alles aber auch nur falls Du die Einzelwerte tatsächlich irgendwo benötigst oder der C-Code die Werte in dem Array verändert. Ansonsten könnte man an der Stelle direkt eine entsprechend lange Zeichenkette übergeben.
Und dann den Style Guide for Python Code zur Namensschreibweise. Und werd bitte diese hässliche ungarische Notation los.
Bei `fObj` handelt es sich um ein `wave.Wave_read`-Objekt vermute ich mal. Das man die `readframes()`-Methode mit einer Gleitkommazahl < 1 aufrufen kann ist, hm, überraschend. Das würde ich sein lassen, oder zumindest kommentieren was dieser Hack macht und warum gerade 0.4 als Wert.
Die Umkodierung von `sample` ist umständlich. Falls das ein Byte sein sollte gibt es `ord()`, ansonsten das `struct`-Modul. Oder das `array`-Modul. Oder halt gleich `ctypes` um eine Zeichenkette mit entsprechend vielen Bytes direkt in das Array zu kopieren. Das alles aber auch nur falls Du die Einzelwerte tatsächlich irgendwo benötigst oder der C-Code die Werte in dem Array verändert. Ansonsten könnte man an der Stelle direkt eine entsprechend lange Zeichenkette übergeben.
hey , hab mir das Guide mal anegschaut. und es in eine for Schleife umgemünzt.
Der wert 0.4 bewirkt das ich nur ein Frame auslese. Ich muss diese frames getrennt als bloc verpacken. Das sind sind interger-Werte von 0 bis 32767.
Wie bekomm ich dei Werte denn nun am besten in ein c_array?
Der wert 0.4 bewirkt das ich nur ein Frame auslese. Ich muss diese frames getrennt als bloc verpacken. Das sind sind interger-Werte von 0 bis 32767.
Wie bekomm ich dei Werte denn nun am besten in ein c_array?
@gosi: wie schon BlackJack geschrieben hat, kannst Du den String, den Du von readframes zurückbekommst, direkt an Deine C-Funktion als Pointer weitergeben, wenn Du readonly darauf zugreifen willst.
Ansonsten einfach aus dem String ein Short-Array machen:
Ansonsten einfach aus dem String ein Short-Array machen:
Code: Alles auswählen
short_array = ctypes.c_short * 13
data = short_array.from_buffer_copy('abcdefghijklmnopqrstuvwxyz')-
BlackJack
@gosi: Um *einen* Frame zu lesen musst Du an die Methode `readframes()` eine *1* übergeben. Weil man der Methode die Anzahl der Frames übergeben muss die man lesen möchte. Dass dort überhaupt ein Dezimalbruch kleiner als 1 möglich ist, halte ich für sehr überraschend und für ein Implementierungsdetail auf das man sich nicht verlassen sollte. Ich hätte da eine Ausnahme erwartet oder das die 0.4 auf 0 abgerundet wird.
@Sirius3: Jetzt machst Du da das gleiche weswegen ich das `array`-Modul nicht verwenden würde. `c_short` ist nicht zwingend 16 Bit gross.
@Sirius3: Jetzt machst Du da das gleiche weswegen ich das `array`-Modul nicht verwenden würde. `c_short` ist nicht zwingend 16 Bit gross.
