python ctypes,通过引用传递双指针

标签 python c ctypes

问题

我正在尝试使用具有以下原型(prototype)的 c 库中的函数:
int glip_get_backends(const char ***name, size_t *count);
这里的 name 参数是问题所在。它是一个通过引用传递的 2 维字符数组。在 C 中,该函数的用法如下:

const char** name;
size_t count;
glip_get_backends(&name, &count);
for (size_t i = 0; i < count; i++) {
    printf("- %s\n", name[i]);
}

现在我想使用 ctypes 从 python 使用这个函数。


我尝试过的

对我来说最合乎逻辑的方法是在 python 中执行此操作:

lglip = CDLL("libglip.so")
count = c_int(0)
backends = POINTER(POINTER(c_char))
lglip.glip_get_backends(byref(backends), byref(count))

导致错误信息

TypeError: byref() argument must be a ctypes instance, not '_ctypes.PyCPointerType'


下一个方法是使用 POINTER() 函数三次并省略 byref(),但这会导致以下错误:

ctypes.ArgumentError: argument 1: : Don't know how to convert parameter 1


然后我从this question中得到灵感并提出以下内容:

lglip = CDLL("libglip.so")
count = c_int(0)
backends = POINTER(POINTER(c_char))()
lglip.glip_get_backends(byref(backends), byref(count))
for i in range(0, count.value):
    print backends[i]  

backends 的定义之后添加 () 出于某种原因我没有完全理解已经修复了调用,但我得到的输出是:

< ctypes.LP_c_char object at 0x7f4592af8710 >
< ctypes.LP_c_char object at 0x7f4592af8710 >

似乎我无法在 python 中使用一个迭代器迭代二维 c 数组,因为它没有正确地取消引用它。

最佳答案

在意识到在 C 实现中 %s 用于遍历子字符串后,我想出了以下可行的解决方案:

lglip = CDLL("libglip.so")
count = c_int(0)
backends_c = POINTER(c_char_p)()
lglip.glip_get_backends(byref(backends_c), byref(count))
backends = []
for i in range(0, count.value):
    backends.append(backends_c[i])
print backends

更新:将 POINTER(POINTER(c_char))() 更改为 POINTER(c_char_p)(),如 eryksun建议。这样我就可以轻松访问字符串。

关于python ctypes,通过引用传递双指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30324758/

相关文章:

python - 如何通过python中的beautiful soup在html页面中找到特定的单词?

python - 使用python将csv转换为json

c - Linux TCP 服务器 : reading client's IP address before accepting connection

c - 正态分布/标准差

C++分配内存问题

python - np.add.types列出的字符是什么意思?

python - 如何使用循环从表中抓取数据以使用 python 获取所有 td 数据

python - 分解高度分支的解析器的大多数 pythonic 方法

c - C 中的整数溢出和数字错误防御

Python ctypes 生成器