![](/img/trans.png)
[英]How do you correctly pass a pointer between calls with Python C-API
[英]How do you pass around a void pointer between Python and C when writing an extension?
我今天開始使用我的第一個Python擴展,並且只是在C庫周圍創建一個非常小的包裝器作為練習。 與C庫一樣,您可以從初始化函數開始,生成處理程序。 您可以將該處理程序傳遞給函數,然后將其傳遞給釋放內存的清理函數。
當我開始編寫包裝器時,我基本上想要一種從python調用每個本機C函數的方法。 很快,我遇到了一個問題,我需要從C返回一個任意指針到Python,只是在另一個函數中再從那里再到C。 我不管它看起來如何,因為我不在Python中使用它,我只是存儲它並傳遞它。
那么如何在Python和C之間傳遞一個void指針呢?
請注意:我知道不建議使用擴展系統編寫這樣的小包裝,而是使用ctypes和朋友。 這只是為了練習。
經過一番搜索,我找到了函數PyLong_AsVoidPtr和PyLong_FromVoidPtr 。 這產生了一種在void *
和PyObject
之間進行轉換的好方法:
# in init function
return PyLong_FromVoidPtr(handle);
# in function using handle
handle = PyLong_AsVoidPtr(python_handle);
現在的一個問題可能是如何從給定函數的典型*args
檢索python_handle
:
PyObject *python_handle;
PyArg_ParseTuple(args, "O", &python_handle);
注意:為"O"
對象提供的參數必須是指向PyObject
指針的指針: PyObject **
。 "O"
本身僅表示通過此PyObject
而不進行任何處理和轉換。 有了這個,你可以隨心所欲地傳遞任何指針。
注意 :我認為這個解決方案並不是很漂亮,因為你現在需要變量,只需要很短的時間。
可以濫用PyLong_FromVoidPtr()和PyLong_AsVoidPtr()將惡意數據注入程序。 我建議反對他們。
Python擁有PyCapsule來完成這項工作。 Capsules提供了一種在模塊或Python空間和C空間之間交換void ptr的安全方法。 膠囊也是類型安全的。 如果需要一些示例,socket / ssl模塊和pyexpat / _elementtree模塊使用tape來交換CAPI結構。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.