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