将 char* 中的非垃圾值从 C 函数返回到 Swig 中的 python



我正在尝试使用python脚本中的C函数。此函数返回一个数组char*。 该函数如下所示:

char* getData(char* id) {
char* old_place = malloc(sizeof(char) * 256);
if (modifyArr(id,old_place) == 0) {
return old_place;
}
return NULL;
}

在Python中,我有:

old = Data.getData(id)

我收到以下错误:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xc8 in position 0: invalid continuation byte

那是因为old_place没有使用其所有256字符,然后我有通过的垃圾值。如何仅返回非垃圾值?

编辑:关于字符串终止符(''(,在modifyArr中我像这样更改old_place

sscanf(line," %s ",old_place);

我读取了文件的行以及插入到old_place中的所需行,因此我不确定如何添加字符串终止符。

两个选项:

  1. 修改 C 函数,使其实际上只返回"有用"数据,调整数组大小并使其成为有效的 UTF-8 字符串。
  2. 使用ctypes.c_char_p在 Python 中强制转换调用的结果。

您实际需要的东西显然取决于具体情况。


如果您正在使用 ASCII 值,方法 1 可以像这样完成:

char* getData(char* id) {
char* old_place = malloc(sizeof(char) * 256);
size_t i;
if (modifyArr(id, old_place) == 0) {
for (i = 0; i < 256-1; i++) {
if (old_place[i] > 127)
break; // Stop at the first non-ASCII value.
}
old_place[i] = ''; // Correctly terminate the string.
return old_place;
}
return NULL;
}

这将生成一个有效的字符串,您将能够在 Python 中使用它。


方法 2 可以像这样完成:

import ctypes
mylib = ctypes.cdll.LoadLibrary('./mylib.so')
data_id = "something"
data = (ctypes.c_char_p)(mylib.getData(data_id))
# data.value is now a bytes() object
print(data.value)

输出:

b'abcdwhateverxfdx8axc5x7f...'

尝试将bzero应用于old_place

char* getData(char* id) {
char* old_place = malloc(sizeof(char) * 256);
bzero(old_place, 256);
if (modifyArr(id,old_place) == 0) {
return old_place;
}
return NULL;
}

bzero设置为您传入的char*n字节。 因此,通过这种方式,您可以擦除mallocchar*中的所有垃圾值。

请参阅有关此函数的参考: http://man7.org/linux/man-pages/man3/bzero.3.html

编辑

根据评论更新答案,感谢MFisherKDX

或者更恰当地将memset应用于old_place

char* getData(char* id) {
char* old_place = malloc(sizeof(char) * 256);
memset(old_place, 0, 256);
if (modifyArr(id,old_place) == 0) {
return old_place;
}
return NULL;
}

memset设置您传入的第一个n个字节char*,并charASCII 表中的哪个数字作为第二个参数传递。 在您的情况下,使用 0(即(作为写入char*char

参考资料memset: https://www.tutorialspoint.com/c_standard_library/c_function_memset.htm

编辑2:好的,很公平,calloc比上面的操作更简单。 只需替换函数中calloc上的malloc

char* getData(char* id) {
char* old_place = calloc(256, sizeof(char));
if (modifyArr(id,old_place) == 0) {
return old_place;
}
return NULL;
}

calloc执行与malloc相同的操作,并将写入所有分配的字节。

最新更新