Seite 1 von 1
unicode - utf-8
Verfasst: Mittwoch 1. Oktober 2014, 13:02
von lightos
Such eine elegante Lösung für folgendes Problem:
Dll/so enthält C-Funktionen die unter Windows WCHAR und unter Linux utf-8 verwenden (Windows somit 2-Byte-Zeichen, Linux 1-Byte)
Im C-Code ist das über typedef umgeschaltet und damit ändert sich auch das API.
Wie kann man das nun elegant in Python abbilden: (ohne if-Konstruktion)
Die API-Wrapper müssen an bestimmten Stellen zwischen
ctypes.c_wchar unter Windows
ctypes.c_char unter Linux
umgesetzt werden.
Ideen?
Re: unicode - utf-8
Verfasst: Mittwoch 1. Oktober 2014, 13:59
von BlackJack
@lightos: Ganz ohne Fallunterscheidung wirst Du nicht auskommen. Im Grunde musst Du wie bei C auch ein Alias erstellen das je nach System den entsprechenden Typ beinhaltet:
Code: Alles auswählen
char_type = ctypes.c_wchar if windows else ctypes.c_char
Re: unicode - utf-8
Verfasst: Freitag 3. Oktober 2014, 18:40
von lightos
OK. Klasse. Das hab ich gesucht.
Re: unicode - utf-8
Verfasst: Donnerstag 16. April 2015, 14:08
von lightos
Ergänzung zur Optimierung:
Aktuell haben die so/Dlls eine Funktion, um die Size von char abfragen zu können.
In Python kann so die korrekte Umsetzung dynamisch im wrapper erfolgen.
Re: unicode - utf-8
Verfasst: Donnerstag 16. April 2015, 16:21
von jerch
@lightos:
Übrigens ist es ein Fehler, für ein UTF-8 Zeichen per se ein c_char einzuräumen. UTF-8 ist ein variables Multibyte-Encoding mit bis zu 4 Byte pro Zeichen.
Re: unicode - utf-8
Verfasst: Freitag 11. Dezember 2015, 14:28
von lightos
Ja danke. Aber die Strings sind 0-Zeichen terminiert. Es gibt hier keine Annahme über 1 Zeichen pro Byte.
Re: unicode - utf-8
Verfasst: Freitag 11. Dezember 2015, 14:31
von lightos
Ergänzende Frage dazu:
Unter Windows ist die API entweder ctypes.c_wchar * N oder unter Linux ctypes.c_char * N.
Das Ziel ist nun möglichst simple einen Python-String zu konvertieren.
Der Buffer der von der API zurück kommt ist Null-Terminiert.
Aktuell ist das mit einem "if" gelöst, da ich noch keine passende Python-Konversion gefunden habe. Idee?
Re: unicode - utf-8
Verfasst: Freitag 11. Dezember 2015, 16:12
von snafu
@lightos
Eine Fallunterscheidung ist immer nötig, wenn man in Abhängigkeit von der Umgebung (hier: Betriebssystem) programmiert. Wenn es dir darum geht, grundsätzlich mit verschiedenen Code-Varianten zu arbeiten, dann wäre dies z.B. in dieser Art möglich:
Code: Alles auswählen
if on_windows:
def convert_string(s):
# Windows-specific implementation
else:
def convert_string(s):
# Non-Windows implementation
Für den Anwender ist dann immer nur eine Variante von `convert_string()` ersichtlich. Dies wäre ja so in etwas das, was man in C häufig mittels `#ifdef`-Abfragen bastelt. Bei sehr vielen Unterscheidungen könnte man auch zwei unterschiedliche Module erstellen und je nach Betriebssytem das passende Modul importierten.
Re: unicode - utf-8
Verfasst: Samstag 12. Dezember 2015, 15:29
von jerch
@lightos:
Das hier sollte sowohl für char/wchar-Pointer als auch Arrays unter Python 2.x funktionieren:
Code: Alles auswählen
def convert_cstring(s, encoding='utf-8'):
res = s.value
return res.decode(encoding) if isinstance(res, str) else res