[英]Wrap C Function returning array of unknown size using ctypes python
I am trying to wrap a C function using ctypes, which returns a character array of unknown size. 我试图使用ctypes包装一个C函数,该函数返回未知大小的字符数组。 The function is from the gdal c api , but my question is not specific to that function.
该函数来自gdal c api ,但我的问题并不特定于该函数。
I would like to know if there is a general way of deconstructing the output of a function returning a char** array object of unknown size. 我想知道是否存在解构返回未知大小的char **数组对象的函数输出的一般方法。 In ctypes, this would be
POINTER(c_char_p * X)
where X is not known. 在ctypes中,这将是
POINTER(c_char_p * X)
,其中X未知。
Using the tips from an answer to a similar question , I was able to get the following to work: 使用对类似问题的答案中的技巧,我可以使以下内容起作用:
# Define the function wrapper.
f = ctypes.CDLL('libgdal.so.20').GDALGetMetadata
MAX_OUTPUT_LENGTH = 10
f.restype = ctypes.POINTER(ctypes.c_char_p * MAX_OUTPUT_LENGTH)
f.argtypes = [ctypes.c_void_p, ctypes.c_char_p]
# Example call (the second argument can be null).
result = []
counter = 0
output = f(ptr, None).contents[counter]
while output:
result.append(output)
counter += 1
output = f(ptr, None).contents[counter]
Where output
is the resulting array and ptr
is a ctypes pointer to an open GDALRaster. output
是结果数组,而ptr
是指向打开的GDALRaster的ctypes指针。 The limitation to this is that I have to construct an array with a fixed length before calling the function. 对此的局限性在于,在调用该函数之前,我必须构造一个具有固定长度的数组。 I can guess what the maximum length could be in practical cases, and simply use that.
我可以猜测实际情况下的最大长度是多少,只需使用即可。 But that is arbitrary, and I wonder if there is a way of getting an array pointer without specifying the array's length.
但这是任意的,我想知道是否存在一种无需指定数组长度即可获取数组指针的方法。 In other words:
换一种说法:
Is there a way to do something similar as the example above, but without specifying an arbitrary maximum length? 有没有一种方法可以执行与上面的示例类似的操作,但不指定任意的最大长度?
It turns out, that you can simply pass a pointer to a c_char_p
object without specifying a length as restype argument, if the function output is a null terminated character array. 事实证明,如果函数输出是一个以null终止的字符数组,则只需将指针传递给
c_char_p
对象, 而无需将长度指定为restype参数。 Then you loop through the result until the null element is found, which indicates the end of the array. 然后循环遍历结果,直到找到null元素为止,该元素指示数组的结尾。
So the following works beatifully for my use case: 因此,以下内容很适合我的用例:
# Define the function wrapper, the restype can simply be a
# pointer to c_char_p (without length!).
f = ctypes.CDLL('libgdal.so.20').GDALGetMetadata
f.restype = ctypes.POINTER(ctypes.c_char_p)
f.argtypes = [ctypes.c_void_p, ctypes.c_char_p]
# Prepare python result array.
result = []
# Call C function.
output = f(ptr, None)
# Ensure that output is not a null pointer.
if output:
# Get first item from array.
counter = 0
item = output[counter]
# Get more items, until the array accessor returns null.
# The function output (at least in my use case) is a null
# terminated char array.
while item:
result.append(item)
counter += 1
item = output[counter]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.