Преобразование струнного объекта 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".
Надеюсь, кто-то скажет мне, где это происходит.
Спасибо заранее.
Ответы
Ответ 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.