Per Python module auf eine C++ Bibliothek zugreifen

Python in C/C++ embedden, C-Module, ctypes, Cython, SWIG, SIP etc sind hier richtig.
Antworten
Benutzeravatar
Sr4l
User
Beiträge: 1091
Registriert: Donnerstag 28. Dezember 2006, 20:02
Wohnort: Kassel
Kontaktdaten:

Hallo ich habe mal ein oder zwei Sachen zu Python Erweiterungen in C, die ich nicht so ganz verstehe. Ich denke ich habe das richtig gemacht (siehe Code am Ende)?

Frage 1)
Was mich besonders interessiert ist `void py_destroy(void* ptr)` Funktion. Momentan lösche ich nur die Instanz, aber ich müsste dort auch allen weiteren "Aufräum Code" reinschreiben, wie z.B Locks aufheben und die Verbindung zu Hardware Komponenten schließen oder? Sonst würde bei folgendem Code solche Locks bestehen bleiben:

Code: Alles auswählen

c = CppExt.create()
c = 5
#Nun könnte der Garbage Collector irgendwann `void py_destroy(void* ptr)` aufrufen und ich könnte evt bestehende Zugriffe auf Ressource nicht ordentlich beenden
Frage 2)
So wie ich das verstehe muss man in Python C Erweiterungen besonders bei Thread aufpassen und zum Beispiel Python mit "Py_BEGIN_ALLOW_THREADS" die Möglichkeit zur Abarbeitung von Threads geben. Wie ist es jedoch wenn Threads in der C++ Bibliothek verwendet werden auf die ich keinen Einfluss habe, ist das ein Problem?


Code

CPP Datei: http://www.python-forum.de/pastebin.php?mode=view&s=382
Python setup Datei: http://www.python-forum.de/pastebin.php?mode=view&s=383

Beispiel:

Code: Alles auswählen

import CppExt

c = CppExt.create()
print CppExt.get(c) # 0
CppExt.add(c, 5)
print CppExt.get(c) # 5

del c #for testing `void py_destroy(void* ptr)`

Grüße Lars
BlackJack

@Sr4l: Ad 1) Ja, da muss aller Aufräumcode rein der Ressourcen freigibt von denen die Python-Laufzeitumgebung nichts weiss.

Ad 2) Solange diese Threads nichts an dem inneren Zustand des Python-Interpreters ändern ist das kein Problem. Man muss also bei Callbacks aus diesen Threads aufpassen die so etwas tun (könnten) und dort entsprechend für Synchronisation sorgen.

Bei dem Quelltext scheint mir `destroy_direct()` gefährlich zu sein. Wenn ich das jetzt richtig interpretiere kann man damit ein „Python-Objekt” freigeben/zerstören auch wenn es noch weiterhin von Python-Code aus erreichbar ist. Also man kann danach von Python aus immer noch `get()` oder `set()` auf dem zerstörten Objekt aufrufen.
Benutzeravatar
Sr4l
User
Beiträge: 1091
Registriert: Donnerstag 28. Dezember 2006, 20:02
Wohnort: Kassel
Kontaktdaten:

Okay danke erstmal.

Das mit dem `destroy_direct()` war ein versehen damit habe ich nur Experimentiert.

Ich werde mich jetzt nochmal mit dem neuen Capsule beschäftigen und dann noch mal mit Numpy arrays. Auch das mit dem Referenzen zählen habe ich noch nicht so ganz verstanden. Falls ich da nochmal ein konkretes Problem habe werde ich mich da noch einmal melden.
BlackJack

@Sr4l: Die Möglichkeit Cython zu verwenden besteht nicht? Das nimmt einem eine Menge Boilerplate-Code ab.
Benutzeravatar
Sr4l
User
Beiträge: 1091
Registriert: Donnerstag 28. Dezember 2006, 20:02
Wohnort: Kassel
Kontaktdaten:

So wie ich das verstanden habe geht Ctypes nicht weil es nur mit C funktioniert, das wäre meine erste Wahl gewesen.

Dann habe ich mit SWIG und Cython angeschaut, allerdings muss ich da scheinbar viel Arbeit in das umschreiben der Headerfiles investieren?

Es ist eine realtiv Umfangreiche Bibliothek die ich benutze es ist das eBus SDK von Pleora (http://www.pleora.com/our-products/ebus-sdk). Pleora Module ermöglichen es unter anderem Videostreams von Kameras über das Netzwerk zu transportieren.
BlackJack

@Sr4l: Selber C-Quelltext für die API zu schreiben macht weniger Arbeit als die Header-Files anzupassen beziehungsweise Wrapper mit Cython zu schreiben? Cython ist doch eigentlich das selbe wie C-Quellext zu schreiben, nur dass man eine Python-ähnliche Syntax hat und einem Boilerplate-Code abgenommen wird. Ich hätte jetzt gedacht das wäre einfacher als das von Hand zu schreiben. (Habe selbst damit noch kein C++ gewrappt.)
Minni
User
Beiträge: 1
Registriert: Dienstag 24. Juni 2014, 12:36

Hallo Sr4l,

hast du es geschafft, die Kamera mit Python anzusteuern? Ich versuche grade eine Flir A325G (inkl. IPort PT1000-ST FLR IEngine --> Pleora) mit Python zu verknüpfen, leider bisher aber ohne Erfolg...
Habe bei der Software GenICam im Ordner /bin eine .py Datei gefunden, die evtl. helfen könnte (umgewandelt durch SWIG), aber ein Abgleich mit den C-Befehlen zeigt, dass dort große Differenzen zu finden sind. Wahrscheinlich kann man die Kamera über die Befehle schon gut nutzen, nur leider weiß ich nicht, wie ich Sie verbunden bekomme...

Ich würde mich sehr freuen, wenn du mir antwortest, da ich dann weiß, ob es eine Aussicht auf Erfolg gibt :)

Viele Grüße,
Minni
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Sr4l hat geschrieben:Dann habe ich mit SWIG und Cython angeschaut, allerdings muss ich da scheinbar viel Arbeit in das umschreiben der Headerfiles investieren?
Für SWIG musst Du in der Regel die Header-Dateien nicht umschreiben. Die meisten meiner SWIG i-Dateien sehen etwa so aus

Code: Alles auswählen

%{
#include "beispiel/modul_a/meine_klasse.h"
%}
%include "beispiel/modul_a/meine_klasse.h"
meine_klasse.i SWIG Datei für meine_klasse.h Header-Datei.

Oh, hab gerade gesehn, dass der Thread schon ziemlich alt ist, ich habe nur auf das Datum vom letzten Eintrag geachtet.
a fool with a tool is still a fool, www.magben.de, YouTube
Benutzeravatar
Sr4l
User
Beiträge: 1091
Registriert: Donnerstag 28. Dezember 2006, 20:02
Wohnort: Kassel
Kontaktdaten:

Minni hat geschrieben:hast du es geschafft, die Kamera mit Python anzusteuern? Ich versuche grade eine Flir A325G (inkl. IPort PT1000-ST FLR IEngine --> Pleora) mit Python zu verknüpfen, leider bisher aber ohne Erfolg...
Habe bei der Software GenICam im Ordner /bin eine .py Datei gefunden, die evtl. helfen könnte (umgewandelt durch SWIG), aber ein Abgleich mit den C-Befehlen zeigt, dass dort große Differenzen zu finden sind. Wahrscheinlich kann man die Kamera über die Befehle schon gut nutzen, nur leider weiß ich nicht, wie ich Sie verbunden bekomme...
Python Dateien im GenICam Ordner o.ä sind mir nie aufgefallen.

Ich hatte eine Infratec VarioCAM hr head <irgendeine nummer> mit einem IPort PT1000-CL. Ich habe es zumindest "ausreichend" geschafft ;-) . Serielle Verbindung und Rohbilder (16bit Int) Abfrage (>15 Bilder/s) und Umrechnung in ein Temperaturbild (Kelvin). Bei Fehlern während der Verbindung (tritt bei langen Kabeln auf) schmiert mir mein Python Modul jedoch ab und reißt den Interpreter mit, wobei der C++ Code diese Problem nicht besitzt.

Ich habe es über C++ und dann diesen Code wie am Anfang beschrieben in einer Python C Erweiterung genutzt. War dann lauffähig unter Windows und Linux (Ubuntu 12.04, ebus sdk 3.0.5)

Wenn ich dir helfen kann dann meld dich bei mir dann versuche ich mich zu erinnern.
Antworten