是的,你應該,因爲它爲什麼工作是因爲ctypes的猜測。將int test_i(int i)
替換爲int test_i(char i)
,您將得到堆棧損壞 - 因爲Python端提供了4或8字節的功能,而C端只能讀取1個字節。根據平臺的不同,這可能會被忽略一段時間,或者逐漸吃掉你的堆棧,或者立即崩潰,或者什麼都不會發生 - 無論如何,這種代碼風格會有異味。
做了基本的類型轉換,但它在很多情況下都沒有幫助,因爲Python類型系統比C更簡單。例如,由於Python整數沒有大小,Python方面無法確定是否傳遞1字節,2字節,4字節或8字節整數。 Python只有雙精度浮點數,而C端也有單精度浮點數和一半精度浮點數,並且可能還有平臺特定的精度。字符串和字節只在Python端分開,而在C端使用Unicode通常是一團糟。目前尚不清楚您是否想要使用wchar_t[]
或char[]
,您希望如何終止您的字符串,並且您是否需要此操作,以及您希望如何解決Python字符串不可變性問題。如果沒有正確的argtypes
,則無法輕鬆傳遞結構和數組。
此外,也別忘指定restype
:
libc.test_f.restype = c_int
默認情況下假定所有功能回到int
,不管它是您的平臺。根據調用約定,CPU寄存器可能會用於返回結果 - 在這種情況下,您不會受到傷害,因爲寄存器是否被讀取沒有區別。在其他情況下,結果是通過堆棧傳遞的,並且由於沒有消耗足夠的堆棧(以及過度消耗)而導致堆棧損壞,函數的RET
將彈出錯誤的地址並在最佳情況下向SIGSEGV打招呼。最糟糕的是,黑客會利用你的應用程序進行欺騙。
一般來說,argtypes
和restype
是你的朋友,因爲他們保護您的代碼在不可預知的方式分崩離析,而他們需要只是因爲一切是太多不同使用C和Python。如果不是,沒有人會因爲禪宗和電池而迫使你使用這些。