Python ctype: массив символов в c функция не обновляется, когда функция c записывает значения в нее - PullRequest
2 голосов
/ 29 апреля 2020

Вот мой C код:

//int MyFunc(char* res); -> This is the definition of C function
char data[4096];  
MyFunc(data);
printf("Data is : %s\n", data);

Переменная data обновляется функцией C. Я использовал bytearray в Python, чтобы передать переменную в качестве аргумента, но обновленный массив не отражает. Любой пример рабочего кода приветствуется.

РЕДАКТИРОВАТЬ: я использую Python 3.7. Мой Python код:

data = bytearray(b'1234567890')
str_buffer = create_string_buffer(bytes(data), len(data))
print(MyFunc(str_buffer))
print(str_buffer.value) #Output: b''

str_buffer не содержит значений, обновленных MyFunc(). Звонок MyFunc() с C# с использованием подписи ниже работает для меня. Я ищу Python 3,7 эквивалента.

[DllImport("mydll.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern int MyFunc(StringBuilder data);

1 Ответ

2 голосов
/ 29 апреля 2020

A bytearray - неправильный способ передачи char * в C функцию. Вместо этого используйте create_string_buffer. Кроме того, len(data) является ошибкой, которая приводит к отсутствию нулевого терминатора, поэтому либо добавьте + 1 к этому, либо удалите его, так как длина по умолчанию верна. Вот минимальный рабочий пример. Во-первых, функция C, которая переводит каждую букву в верхний регистр и возвращает количество букв, которые уже были прописными:

#include <ctype.h>

int MyFunc(char* res) {
    int i = 0;
    while(*res) {
        if(isupper(*res)) {
            ++i;
        } else {
            *res = toupper(*res);
        }
        ++res;
    }
    return i;
}

Я скомпилировал ее с помощью gcc -fPIC -shared upstring.c -o upstring.so. Поскольку вы находитесь на Windows, вам придется адаптировать это.

Теперь некоторые Python, которые его называют:

from ctypes import *
upstring = CDLL("./upstring.so") # Since you're on Windows, you'll have to adapt this too.
data = bytearray(b'abc12DEFGHI')
str_buffer = create_string_buffer(bytes(data)) # Note: using len(data) would be an off-by-one error that would lose the null terminator, so either omit it or use len(data)+1
print(upstring.MyFunc(str_buffer)) # prints 6
print(str_buffer.value) # prints b'ABC12DEFGHI'
...