簡體   English   中英

使用ctypes python包裝C函數返回未知大小的數組

[英]Wrap C Function returning array of unknown size using ctypes python

我試圖使用ctypes包裝一個C函數,該函數返回未知大小的字符數組。 該函數來自gdal c api ,但我的問題並不特定於該函數。

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

使用對類似問題答案中的技巧,我可以使以下內容起作用:

# 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是指向打開的GDALRaster的ctypes指針。 對此的局限性在於,在調用該函數之前,我必須構造一個具有固定長度的數組。 我可以猜測實際情況下的最大長度是多少,只需使用即可。 但這是任意的,我想知道是否存在一種無需指定數組長度即可獲取數組指針的方法。 換一種說法:

有沒有一種方法可以執行與上面的示例類似的操作,但不指定任意的最大長度?

事實證明,如果函數輸出是一個以null終止的字符數組,則只需將指針傳遞給c_char_p對象, 而無需將長度指定為restype參數。 然后循環遍歷結果,直到找到null元素為止,該元素指示數組的結尾。

因此,以下內容很適合我的用例:

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM