Python ctypes : How to modify an existing char* array

标签 python pointers function-pointers ctypes

我正在开发一个使用 C 库 libupnp 的 Python 应用程序。我正在使用 CTypes 来使用足够简单的库。我遇到的问题是当我为读取请求注册回调函数时。该函数具有以下形式的原型(prototype):

int read_callback(void *pFileHandle, char *pBuf, long nBufLength);

pFileHandle 只是一些文件句柄类型。 pBuf 是一个可写内存缓冲区。这是数据输出的地方。 nBufLength 是要从文件中读取的字节数。返回一个状态码。

我有一个 Python 函数指针。这很容易实现,但是当我定义一个 Python 函数来处理这个回调时,我发现 pBuf 没有被写入,因为 Python 字符串是不可变的,当你分配或修改它们时,它们会创建新的实例。这带来了一个大问题,因为 C 库期望在函数完成请求的文件数据时返回 char 指针。由于 Python 字符串的方式,每次缓冲区最终都是空的。有没有办法在不修改 C 库的情况下解决这个问题?

处理程序应该修改给定的缓冲区参数,这是我的问题。

所以我想要发生的是调用 Python 函数来执行某个文件的读取(可能在内存中、文件系统句柄中或介于两者之间的任何文件中)。 pBuf 参数由流的读取填充(同样在 Python 中)。然后回调返回到已写入 pBuf 的 C 代码。

最佳答案

回调是用 pBuf 和 nBufLength 调用的。 pBuf 已经分配了可写内存,但如果您请求 pBuf.value,它会被转换为不可变的 python 字符串。

而是将 pBuf 转换为可以直接修改的对象:

## If pBuf is c_char_p, then convert to writable object
c = ctypes.cast(pBuf, ctypes.POINTER(ctypes.c_char))
## At this point, you can set individual bytes
## with c[i] = x, but this is dangerous and there's a safer way:

## get address of string
addr = ctypes.addressof(c.contents)

## convert to char[] for safe writing
c2 = (c_char*nBufLength).from_address(addr)

## see how many bytes to write
nb = min(len(msg), nBufLength-1)

c2[:nb] = msg[:nb]
c2[nb+1] = '\0'

关于Python ctypes : How to modify an existing char* array,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14310310/

相关文章:

python - 根据 2 个条件从数据框中删除行

java - 将 python (".py") 文件与 Web 应用程序的 java 类文件捆绑在一起

c - 尝试在 C 中分配和调用嵌套结构的值时出现“段错误”错误

c++ - 双指针动态分配

c++ - 如何在 C++ 中返回数据的拷贝

c - 那么函数指针的*可以省略吗?

c - 将 C++ lambda 传递给旧的 C 函数指针

python - 根据Python中另一个文件中的元素对文本文件进行排序

python - 使用 Pandas 数据框中的部分数据滚动标准差

c++ - 从结构调用 C++ 成员函数指针