簡體   English   中英

將C數據結構和C API導出到Python

[英]Exporting C data structures and a C API to Python

我有使用C API的C庫的源代碼。 我想向python公開函數和C數據結構,以便可以在python腳本中使用該庫。

有200多個函數和大約50個數據結構,因此,如果我能自動在C和Python之間生成“膠水”代碼,那將是更好的選擇。

我目前正在閱讀SWIG,因為這似乎是前進的方向。 我還應該考慮其他替代方法(為什么?)。

最后但並非最不重要的一點(假設SWIG是前進的方向),是否有人鏈接到一個不錯的教程,該教程顯示了如何從現有C庫編寫Python擴展模塊?

我無法評論SWIG,但我可以強烈推薦Cython教程包裝C庫 )。 它確實需要手工編寫包裝器代碼,但是至少包裝器代碼幾乎是Python,並且您可能仍然需要進行一些輸入驗證/轉換和class包裝,這在很大程度上Cython可以實現自動化。

另一個選擇是Cython的前任Pyrex

我已經使用SWIG 2.x轉換了非常復雜的C和C ++ API,它為我節省了很多時間。

SWIG中的一個重要限制是,結構中的結構不能很好地處理。 C ++中的類也是如此。 我對C / C ++ API擁有完全的控制權,因此在此之前,我先弄平了我使用內部結構的兩個結構,避免了這個問題。

我的第一個建議是為SWIG定義一個基本模塊,該模塊僅導入您的頭文件,並查看SWIG的喜歡程度。 像編譯器一樣,SWIG將輸出警告和發現的錯誤,而這正是您將需要進行的工作。

在我完成所有功能后,我對結果並不完全滿意。 SWIG會按字面意義翻譯所有函數,但問題是在C / C ++中很常見的一些慣用法在Python中看起來很奇怪。 例如,將輸出參數指定為指針的函數不是Python語言。 例如,考慮以下功能,這在C / C ++中很常見:

unsigned int getPath(char* buffer, unsigned int size);

此函數需要一個緩沖區和一個大小,並用字符串填充緩沖區,返回實際使用的字節數,如果出錯則返回0。 在Python中,必須發送一個緩沖區(一個字符串)和一個大小作為參數將是非常奇怪的,因此對於這種樣式的函數,我添加了替代版本以轉換為更友好的函數。 在這種情況下,我做了這樣的事情:

const char* getPath();

此函數的實現只是將一個最大大小的靜態緩沖區傳遞到原始getPath() ,並返回靜態緩沖區的地址,如果有錯誤,則返回NULL。 免責聲明:我使用C ++編譯器,因此可以定義兩個具有不同參數的getPath()函數。 在C語言中,您需要為每個函數使用不同的名稱。 SWIG自動將char *轉換為Python字符串,因此轉換效果非常好。

除了在C / C ++中定義替代函數之外,您還可以向SWIG提供有關如何轉換某些函數及其參數的說明。 例如,SWIG允許您綁定一對buffer和size參數,並將其視為已轉換函數上的單個字符串參數。 還有更多類似這樣的便捷翻譯。

就教程而言,我在正式的SWIG文檔之外沒有發現任何有用的東西,這非常好,並且有專門針對Python的部分。

我希望這有幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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