Подтвердить что ты не робот

Преобразование струнного объекта python в c char * с использованием ctypes

Я пытаюсь отправить 2 строки из Python (3.2) в C, используя ctypes. Это небольшая часть моего проекта на моей малиновой пи. Чтобы проверить, правильно ли выполнялась функция C, я помещаю один из них в текстовый файл.

Код Python

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-код

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..
}

Проблема

В текстовом файле появляется только первая буква строки.

Я пробовал много способов конвертировать строковый объект Python с помощью ctypes.

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

При этих преобразованиях я все время получаю ошибку "неправильный тип" или "байты или целочисленный адрес, ожидаемый вместо экземпляра str".

Надеюсь, кто-то скажет мне, где это происходит. Спасибо заранее.

4b9b3361

Ответ 1

Благодаря Эрыксуну решение:

Код Python

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)

Ответ 2

Я думаю, вам просто нужно использовать c_char_p() вместо create_string_buffer().

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))

Если вам нужны изменяемые строки, используйте create_string_buffer() и переведите их в c_char_p с помощью ctypes.cast().

Ответ 3

Считаете ли вы использование SWIG? Я сам не пробовал, но вот как бы он выглядел, не меняя свой источник C:

/*mymodule.i*/

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

Это сделает ваш источник Python таким же простым, как (пропуская компиляцию):

import mymodule

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

Примечание. Я не уверен, что .encode('utf-8') необходим, если ваш исходный файл уже UTF-8.