我正在使用 Cython 將 C 庫與 Python 介面。一個庫函式回傳一個型別為 null 的字串陣列,char**
我想將其轉換list
為str
. 下面的代碼有效,但它看起來很脆弱和笨重,我想知道是否有更簡單的方法來做到這一點:
# myfile.pyx
from cython.operator import dereference
def results_from_c():
cdef char** cstringsptr = my_c_function()
strings = []
string = dereference(cstringsptr)
while string != NULL:
strings.append(string.decode())
cstringsptr = 1
string = dereference(cstringsptr)
return strings
特別是,是否可以cstringsptr = 1
像在 C 中使用 eg 那樣獲取陣列中的下一個字串cstringsptr ;
?這通常是一種將陣列轉換為串列的可靠方法嗎?如果例如記憶體分配失敗或字串不是空終止的并且它永遠回圈怎么辦?在我看來,應該有一種更簡單的方法來用 Cython 做到這一點。
uj5u.com熱心網友回復:
要完成@alexis 的答案,就性能而言,使用append
速度很慢(因為它在內部使用了一個不斷增長的陣列),并且可以用直接索引來代替。這個想法是執行兩次步行以了解字串的數量。雖然兩次步行似乎很昂貴,但事實并非如此,因為編譯器應該優化這個回圈。如果代碼以最高優化級別 ( -O3
) 編譯,則第一個回圈應使用非常快的 SIMD 指令。一旦知道長度,就可以以更快的方式分配/填充串列。字串解碼應該花費大量時間。默認使用 UTF-8 解碼。這有點貴,如果已知字串不包含特殊字符,那么使用 ASCII 解碼應該會更快一些。
這是未經測驗的代碼示例:
from cython.operator import dereference
def results_from_c():
cdef char** cstringsptr = my_c_function()
cdef int length = 0
cdef int i
string = dereference(cstringsptr)
while string != NULL:
cstringsptr = 1
length = 1
string = dereference(cstringsptr)
cstringsptr -= length
# None is just a null pointer so that this just allocates a 0-filled array
strings = [None] * length
for i in range(length):
string = dereference(cstringsptr i)
strings[i] = string.decode()
return strings
這使得代碼更加復雜。
uj5u.com熱心網友回復:
如果您正在使用有效的 C 資料結構,則字串將以空值結尾。問題是,字串指標陣列是如何終止的?庫(或my_c_function()
)確保在最后一個字串指標之后有一個 NULL,或者以其他方式使陣列長度可用。確保你知道它是什么,并且不要讓你的回圈在一個空指標上終止,除非你保證會有一個。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/430728.html
上一篇:C 指標的作用域是什么?