Vorausgesetzt, man möchte ein Erweiterungsmodul schreiben, das eine Python-Zeichenfolge an die C-Bibliotheksfunktion übergeben muss. Es stellt sich also die Frage, ob Unicode richtig gehandhabt werden soll. Eines der Hauptprobleme ist, dass vorhandene C-Bibliotheken Pythons native Darstellung von Unicode nicht verstehen. Daher besteht die größte Herausforderung darin, die Python-Zeichenfolge in eine Form zu konvertieren, die von C-Bibliotheken leichter verstanden werden kann.

Zur Veranschaulichung der unten aufgeführten Lösung werden zwei C-Funktionen verwendet, die Zeichenfolgendaten verarbeiten und zum Debuggen und Experimentieren ausgeben.

Code 1: Verwendet die im Formular angegebenen Bytes char *, int

void print_chars(char *s, int len) 
{ 
    int n = 0; 
    while (n < len) 
    { 
        printf("%2x ", (unsigned char) s[n]); 
        n++; 
    } 
    printf("\n"); 
} 

 
Code 2: Verwendet breite Zeichen im Formular wchar_t *, int

void print_wchars(wchar_t *s, int len) 
{ 
    int n = 0; 
    while (n < len) 
    { 
        printf("%x ", s[n]); 
        n++; 
    } 
    printf("\n"); 
} 

Python-Strings müssen für die byteorientierte Funktion in eine geeignete Bytecodierung wie UTF-8 konvertiert werden print_chars(). Der unten angegebene Code ist eine einfache Erweiterungsfunktion, die den Zweck löst.



Code # 3:

static PyObject *py_print_chars(PyObject *self, PyObject *args) 
{ 
    char *s; 
    Py_ssize_t len; 
    if (!PyArg_ParseTuple(args, "s#", &s, &len)) 
    { 
        return NULL; 
    } 
    print_chars(s, len); 
    Py_RETURN_NONE; 
} 

Für Bibliotheksfunktionen, die mit dem nativen Maschinentyp arbeiten wchar_t , kann der C-Erweiterungscode wie folgt geschrieben werden:

Code # 4:

static PyObject * py_print_wchars(PyObject * self, PyObject * args) 
{ 
    wchar_t * s; 
    Py_ssize_t len; 
    if (! PyArg_ParseTuple(args, "u#", &s, &len)) 
    { 
        return NULL; 
    } 
    print_wchars(s, len); 
    Py_RETURN_NONE; 
} 

Der folgende Code überprüft nun, wie die Erweiterungsfunktionen funktionieren.

Es ist zu beachten, wie die byteorientierte Funktion print_chars()UTF-8-codierte Daten print_wchars()empfängt , während sie die Unicode-Codepunktwerte empfängt.

Code # 5:

s = 'Spicy Jalape\u00f1o'
print (print_chars(s)) 
  
print ("\n", print_wchars(s)) 

Ausgabe :

53 70 69 63 79 20 4a 61 6c 61 70 65 c3 b1 6f
53 70 69 63 79 20 4a 61 6c 61 70 65 f1 6f

Lassen Sie uns die Art der C-Bibliothek überprüfen, auf die zugegriffen wird. Für viele C-Bibliotheken ist es möglicherweise sinnvoller, Bytes anstelle einer Zeichenfolge zu übergeben. Verwenden wir dazu den unten angegebenen Konvertierungscode.

Code # 6:

static PyObject *py_print_chars(PyObject *self, PyObject *args) 
{ 
    char *s; 
    Py_ssize_t len; 
      
    
      
    if (!PyArg_ParseTuple(args, "y#", &s, &len)) 
    { 
        return NULL; 
    } 
    print_chars(s, len); 
    Py_RETURN_NONE; 
} 

Wenn Sie dennoch Zeichenfolgen übergeben möchten, ist darauf zu achten, dass Python3 eine anpassbare Zeichenfolgendarstellung verwendet, die mit den Standardtypen char * oder nicht ganz einfach direkt C-Bibliotheken zugeordnet werden kann wchar_t *. Um C Zeichenfolgendaten zu präsentieren, ist daher fast immer eine Art Konvertierung erforderlich. Die Formatcodes s # und u # , PyArg_ParseTuple()um solche Konvertierungen sicher durchzuführen.
Bei jeder Konvertierung wird eine Kopie der konvertierten Daten an das ursprüngliche Zeichenfolgenobjekt angehängt, damit sie später wieder verwendet werden können, wie im folgenden Code gezeigt.

Code # 7:

import sys 
  
s = 'Spicy Jalape\u00f1o'
print ("Size : ", sys.getsizeof(s)) 
  
print("\n", print_chars(s)) 
  
print ("\nSize : ", sys.getsizeof(s)) 
  
print ("\n", print_wchars(s)) 
  
print ("\nSize : ", sys.getsizeof(s)) 

Ausgabe :

Größe: 87
53 70 69 63 79 20 4a 61 6c 61 70 65 c3 b1 6f
Größe: 103
53 70 69 63 79 20 4a 61 6c 61 70 65 f1 6f
Größe: 163