Konvertieren eines Python-String-Objekts in c char* mit ctypes

Lesezeit: 3 Minuten

Benutzer-Avatar
Kleiner

Ich versuche, 2 Zeichenfolgen von Python (3.2) mit ctypes an C zu senden. Dies ist ein kleiner Teil meines Projekts auf meinem Raspberry Pi. Um zu testen, ob die C-Funktion die Strings korrekt empfangen hat, lege ich einen davon in eine Textdatei.

Python-Code

string1 = "my string 1"
string2 = "my string 2"

# create byte objects from the strings
b_string1 = string1.encode('utf-8')
b_string2 = string2.encode('utf-8')

# send strings to c function
my_c_function(ctypes.create_string_buffer(b_string1),
              ctypes.create_string_buffer(b_string2))

C-Code

void my_c_function(const char* str1, const char* str2)
{
    // Test if string is correct
    FILE *fp = fopen("//home//pi//Desktop//out.txt", "w");
    if (fp != NULL)
    {
        fputs(str1, fp);
        fclose(fp);
    }

    // Do something with strings..
}

Das Problem

Nur der erste Buchstabe der Zeichenfolge erscheint in der Textdatei.

Ich habe viele Möglichkeiten ausprobiert, um das Python-String-Objekt mit ctypes zu konvertieren.

  • ctypes.c_char_p
  • ctypes.c_wchar_p
  • ctypes.create_string_buffer

Bei diesen Konvertierungen bekomme ich immer wieder den Fehler “falscher Typ” oder “Bytes oder Integer-Adresse statt Str-Instanz erwartet”.

Ich hoffe jemand kann mir sagen wo es schief geht. Danke im Voraus.

  • Satz my_c_function.argtypes = [ctypes.c_char_p, ctypes.c_char_p]. Dann, weil die Parameter sind constnennen Sie es einfach als my_c_function(b_string1, b_string2).

    – Eryk Sonne

    25. November 2014 um 14:38 Uhr

  • FYI, ein wörtliches Backslash-Zeichen muss mit Escapezeichen versehen werden "\\", ist aber für einen Schrägstrich nicht erforderlich. Es ist nur "/home/pi/Desktop/out.txt".

    – Eryk Sonne

    25. November 2014 um 14:42 Uhr

  • @eryksun Danke für deine Antwort. Es funktioniert jetzt, ich habe total vergessen, dass ich argtypes noch auf c_wchar_p gesetzt hatte. Was die Schrägstriche angeht, verwechsle ich sie immer.

    – Kleiner

    25. November 2014 um 15:03 Uhr


  • Benutz nur buf = ctypes.create_string_buffer(bstr) wenn die Funktion die Zeichenfolge ändert. Es ist gleichbedeutend mit buf = (ctypes.c_char * (len(bstr) + 1))(); buf.value = bstr.

    – Eryk Sonne

    25. November 2014 um 15:12 Uhr


Benutzer-Avatar
Kleiner

Dank Eryksun die Lösung:

Python-Code

string1 = "my string 1"
string2 = "my string 2"

# create byte objects from the strings
b_string1 = string1.encode('utf-8')
b_string2 = string2.encode('utf-8')

# send strings to c function
my_c_function.argtypes = [ctypes.c_char_p, ctypes.char_p]
my_c_function(b_string1, b_string2)

  • my_c_function.argtypes = [ctypes.c_char_p, ctypes_char_p] Was meinen Sie my_c_function.argtypes = [ctypes.c_char_p, ctypes.char_p] (Notiz . Anstatt von _)?

    – Hallo

    18. November 2019 um 3:54 Uhr

  • Haha, nach 5 Jahren ist es jemandem aufgefallen oder hat sich die Mühe gemacht, darauf hinzuweisen. Danke dafür, ich habe es in der Antwort bearbeitet.

    – Kleiner

    19. November 2019 um 11:43 Uhr

  • Wissen Sie, Zwangsstörungen!

    – Hallo

    26. November 2019 um 15:51 Uhr

  • my_c_function.argtypes = [ctypes.c_char_p, ctypes.char_p] Meinst du my_c_function.argtypes = [ctypes.c_char_p, ctypes.c_char_p] ?

    – a11apurva

    14. September 2021 um 7:22 Uhr

Ich denke, Sie müssen nur c_char_p() anstelle von create_string_buffer() verwenden.

string1 = "my string 1"
string2 = "my string 2"

# create byte objects from the strings
b_string1 = string1.encode('utf-8')
b_string2 = string2.encode('utf-8')

# send strings to c function
my_c_function(ctypes.c_char_p(b_string1),
              ctypes.c_char_p(b_string2))

Wenn Sie veränderliche Zeichenfolgen benötigen, verwenden Sie create_string_buffer() und wandeln Sie diese mit ctypes.cast() in c_char_p um.

Haben Sie darüber nachgedacht, zu verwenden SCHLUCK? Ich habe es nicht selbst ausprobiert, aber so würde es aussehen, ohne Ihre C-Quelle zu ändern:

/*mymodule.i*/

%module mymodule
extern void my_c_function(const char* str1, const char* str2);

Dies würde Ihre Python-Quelle so einfach machen wie (Kompilierung überspringen):

import mymodule

string1 = "my string 1"
string2 = "my string 2"
my_c_function(string1, string2)

Hinweis Ich bin mir nicht sicher .encode('utf-8') ist erforderlich, wenn Ihre Quelldatei bereits UTF-8 ist.

  • Denken Sie für Python 3 daran, swig’s zu verwenden -py3 Möglichkeit. Der Wrapper codiert eine Python 3-Zeichenfolge als UTF-8, indem er verwendet PyUnicode_AsUTF8String und dann PyBytes_AsStringAndSize. Vorbeigehen bytes erhebt a TypeError.

    – Eryk Sonne

    25. November 2014 um 18:21 Uhr


1385580cookie-checkKonvertieren eines Python-String-Objekts in c char* mit ctypes

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy