[英]python ctypes, pass double pointer by reference
I'm trying to use a function in ac library with the following prototype: 我正在尝试使用以下原型在ac库中使用函数:
int glip_get_backends(const char ***name, size_t *count);
The name
argument here is the problem. 这里的name
参数是问题所在。 It is a 2 dimmensional char array passed by reference. 它是通过引用传递的2个dimmensional char数组。 In C the function is used as follows: 在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]);
}
Now I want to use this function from python using ctypes. 现在我想使用ctypes从python中使用这个函数。
The most logical approach to me was doing this in python: 对我来说最合乎逻辑的方法是在python中执行此操作:
lglip = CDLL("libglip.so")
count = c_int(0)
backends = POINTER(POINTER(c_char))
lglip.glip_get_backends(byref(backends), byref(count))
which resulted in the error message 这导致了错误消息
TypeError: byref() argument must be a ctypes instance, not '_ctypes.PyCPointerType' TypeError:byref()参数必须是ctypes实例,而不是'_ctypes.PyCPointerType'
The next approach was to use the POINTER()
function three times and omitting the byref()
, but that results in the following error: 下一种方法是使用POINTER()
函数三次并省略byref()
,但这会导致以下错误:
ctypes.ArgumentError: argument 1: : Don't know how to convert parameter 1 ctypes.ArgumentError:参数1 ::不知道如何转换参数1
Then I took inspiration from this question and came up with the following: 然后我从这个问题中汲取灵感并提出以下建议:
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]
Adding ()
after the definition of backends
for some reason I don't fully comprehend has fixed the call, but the output I get is: 由于某些原因我在backends
的定义后添加()
已经修复了调用,但我得到的输出是:
< ctypes.LP_c_char object at 0x7f4592af8710 > <ctypes.LP_c_char对象位于0x7f4592af8710>
< ctypes.LP_c_char object at 0x7f4592af8710 > <ctypes.LP_c_char对象位于0x7f4592af8710>
It seems I can't itterate over a 2 dimensional c array with one itterator in python, as it does not properly dereference it. 我似乎无法在python中使用一个itterator对二维c数组进行迭代,因为它没有正确地取消引用它。
After realizing that in the C implementation %s
is used to itterate over the substrings I came up with the following working solution: 在意识到在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
Update: changed POINTER(POINTER(c_char))()
to POINTER(c_char_p)()
, as eryksun suggested. 更新:将POINTER(POINTER(c_char))()
更改为POINTER(c_char_p)()
,如eryksun建议的那样。 This way I can easily access the strings. 这样我就可以轻松访问字符串。
If backends members can use index
method, you can use this code: 如果后端成员可以使用index
方法,则可以使用以下代码:
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 ''.join(backends[i][:backends[i].index("0")])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.