python中使用ctypes調用so傳參設置

問題

近日在作一組聲紋聚類時,使用了另外一團隊同窗開發的聲紋距離算法。該算法對外提供的是一組so包,須要使用方本身去使用。在python中調用純so包通常使用ctypes類庫,用起來看起來簡單但也有很多細節容易犯錯。本次使用過程當中,就遇到傳參的問題。python

目標so庫中對外export的函數是大體以下的三個函數:算法

void* create_handler();
    int extract_feature(void* hander);
    bool destroy(void* handler);

這三個函數使用起來倒也簡單,順序使用就能夠了。但發現寫成以下形式的python代碼後,執行會直接segment fault。函數

import sys
    import ctypes
    
    so = ctypes.CDLL("./lib/libbase.so")
    p = so.create_handler()
    feature = so.extract_feature(p)
    so.destroy(p)

解決

這段代碼中p是int類型,由void*自動轉來,在ctyeps中這種轉型自己是沒問題的。segment fault發生在extract_feature函數調用中,問題應當出在參數上,回傳的handler已經不是原來的pointer了,致使訪問指針出錯。指針

查閱ctypes的文檔後,發現ctypes能夠聲明so庫中函數的參數,返回類型。試了試,顯式聲明後問題獲得瞭解決,證實咱們的猜測是對的,確實指針發生了變化。修改後代碼以下:rest

import sys
    import ctypes
    
    so = ctypes.CDLL("./lib/libbase.so")
    so.create_handler.restype=ctypes.c_void_p
    so.extract_feature.argtypes=[ctypes.c_void_p]
    so.destroy.argtypes=[ctypes.c_void_p]
    
    p = so.create_handler()
    feature = so.extract_feature(p)
    so.destroy(p)

結論:

ctypes中傳遞指針類型參數須要顯式聲明c函數的參數,返回類型。
相關文章
相關標籤/搜索