Cython 使用筆記


Cython 使用筆記

前言

最近 bug 改的差不多了,新項目也沒有開始。閑不住,自己又開始折騰,准備使用 Cython 對當前使用的 C 庫進行封裝。目的有以下三個:

  • 對該 C 庫的接口及代碼進行初步了解;
  • 簡化以后對該 C 庫的單元測試開發;
  • 對python和c之間的交互有一個初步了解;

Cython 簡介

Cython 是一門基於 Python 的編程語言, 通過額外的語法允許可選擇的靜態類型聲明。 它的目標是成為 Python 的超集, 而Python 賦予它高級,面向對象,函數式以及動態編程等特性。 使用 Cython 編寫的源代碼會被轉換成優化過的 C/C++ 代碼, 並且被編譯成 Python 的擴展模塊。 這樣即有非常快的程序執行速度和與外部C程序庫的緊密集成, 也可以保持 Python 語言所著稱的高程序員生產力。

本文主要記錄在使用 Cython 過程中遇到的問題。

使用 Cython 過程中的問題

安裝

可以直接下載 windows 二進制安裝包

Unable to find vcvarsall.bat

編譯時提示 error: Unable to find vcvarsall.bat 。已經安裝VC,並且將該 bat 文件路徑加入 Path 環境變量也無法解決問題。在 Cython FAQ 中找到解決方案,如果沒有使用 pyximport ,又安裝了 cygwin ,可以在編譯參數加上參數 --compiler=mingw32 來解決問題。

Python undefined reference

編譯時,出現很多錯誤信息如:

undefined reference to `_imp__PyInt_Type'

需要參照 InstallingOnWindows 中的 Troubleshooting,編譯 libpythonXX.a 。(XX 代表 Python 版本號,如 libpython27.a)

  1. 下載 pexport
  2. 找到 pythonXX.dll
  3. 運行:

    pexports pythonXX.dll > pythonXX.def 

    這樣會提取 pythonXX.dll 的所有符號並將它們寫入 pythonXX.def 。

  4. 運行:

    dlltool --dllname pythonXX.dll --def pythonXX.def --output-lib > libpythonXX.a
    

    這樣會創建 libpythonXX.a

  5. 將 libpythonXX.a 拷入 python 路徑中的 libs 文件夾下。

讀取二進制文件

  1. 打開文件並讀取所有內容為字符串

    data = open("data", "r")
  2. 將字符串強制轉換為 bytes ,賦值給 char* 類型指針

    cdef char* content = <bytes>data 
  3. 將指針轉換為指定類型傳遞給C庫接口

    lib_interface(<TypePTR>content)

導出頭文件宏定義常量

假設在頭文件 interface.h 中存在常量定義:

#define IF_OK 0

將此定義導出需要:

  1. 需要在 lib.pxd 文件中使用 enum 定義該常量

    cdef extern from "interface.h":
        enum: IF_OK
  2. 在 lib.pyx 文件中:

    cimport lib
    
    IF_OK = lib.IF_OK

動態內存分配

可以通過:

from libc.stdlib cimport *

使用 mallocfree 等 C 標准庫函數


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM