【发布时间】:2015-05-19 11:47:09
【问题描述】:
问题
我正在尝试使用具有以下原型的 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() 参数必须是 ctypes 实例,而不是 '_ctypes.PyCPointerType'
下一个方法是使用 POINTER() 函数 3 次并省略 byref(),但这会导致以下错误:
ctypes.ArgumentError: argument 1: : 不知道如何转换参数 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 的定义之后添加() 已修复调用,但我得到的输出是:
似乎我无法在 python 中使用一个迭代器来迭代二维 c 数组,因为它没有正确取消引用它。
【问题讨论】:
-
您是否尝试过迭代后端[i] 中的对象?这是一个二维数组,因此您可能需要为此使用嵌套循环。我不熟悉 ctypes 的用法,只是凭直觉。
-
我可以试试,但我不知道循环的范围。这就是为什么在 C 中它只使用一个迭代器。哦,我刚刚在 C 中意识到它使用 %s,因此打印到 \0。正在努力。
-
您必须将
()添加到backends因为POINTER(POINTER(c_char))是一个类型,类似于c_intvsc_int(0)...first 是类型, 其次是类型的实例。