2017-01-06 55 views
2

我想用ctypes來包裝C函數,它返回一個未知大小的字符數組。該功能是from the gdal c api,但我的問題不是特定於該功能。W包C使用ctypes函數返回未知大小的數組python

我想知道是否有一種解構函數的輸出的一般方法,返回一個未知大小的char **數組對象。在ctypes中,這將是POINTER(c_char_p * X),其中X未知。

answer to a similar question使用技巧,我能得到以下工作:

# 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] 

哪裏output是導致陣列和ptr是一個ctypes指針開放GDALRaster。對此的限制是我必須在調用函數之前構造具有固定長度的數組。我可以猜測在實際情況下最大長度是多少,並簡單地使用它。但是這是任意的,我想知道是否有一種獲得數組指針而不指定數組長度的方法。換句話說:

有沒有辦法做類似上面的例子,但沒有指定任意的最大長度?

回答

0

原來,就可以簡單地將指針傳遞給一個c_char_p對象而不指定長度作爲restype參數,如果函數的輸出是一個空終止字符數組。然後循環查找結果,直到找到空元素,這表示數組的末尾。

所以下面的作品beatifully我用例:

# 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]