Python使用ctypes模塊調用DLL函數之C語言數組與numpy數組傳遞

2021-01-10 編碼那些事

在Python語言中,可以使用ctypes模塊調用其它如C++語言編寫的動態連結庫DLL文件中的函數,在提高軟體運行效率的同時,也可以充分利用目前市面上各種第三方的DLL庫函數,以擴充Python軟體的功能及應用領域,減少重複編寫代碼、重複造輪子的工作量,這也充分體現了Python語言作為一種膠水語言所特有的優勢。

前面兩篇已經講了傳遞數值/指針/字符串參數、傳遞結構體參數的例子,大家可以回看一下,這樣可以更好的理解本次要講的內容。詳細細節請參考:python使用ctypes模塊調用DLL函數之傳遞數值、指針與字符串參數、Python使用ctypes模塊調用DLL函數之傳遞結構體參數

這次講一下在Python中使用ctypes模塊調用DLL中的庫函數傳遞數組參數的情況。一般情況下,DLL函數中傳遞C語言類型的數組,在接收到Python語言中時,通常將其轉換為numpy庫裡面的數組類型,這樣做的好處是可以藉助於numpy強大的分析處理功能對數據直接作後續處理。這次通過例子演示下C語言數組到numpy數組之間是怎樣傳遞的。

同樣,作業系統環境是win7 64位,Python使用的版本是python2.7.14,函數約定的調用方式為C調用(cdecl)方式。

例子說明

在DLL文件中設計一個函數GenSine,其功能是根據給定的參數(包括數據點數N、信號頻率f、採樣頻率Fs、信號幅值A、初始相位initPhase、偏移offset等參數)產生一個正弦波形數據,返回時間向量數組x(橫坐標數據)和波形數據y(縱坐標數據)。該函數的聲明如下圖所示:

函數GenSine的具體C語言實現代碼如下:

下面給出兩種Python中轉為numpy數組的調用方法。

Python中調用方法1

在Python中的調用方式如下:

上面的代碼中在聲明函數的參數類型時,對於前兩個參數x和y數組變量,將其聲明為指向double類型的指針即可。在調用該函數時,先聲明兩個numpy庫中的數組t1、y1,數據類型為float64,將其作為參數傳遞到該函數中時,使用的是numpy中的ctypes.data_as(POINT(c_double))轉化為C語言中的指向double類型的指針類型,這樣就可以實現numpy中數組與C語言數組中的完美轉換。

Python中調用方法2

在Python中的調用方式如下:

與第1種方法不同的是,這種方法在聲明函數的參數類型時,對於前兩個參數x和y數組變量,使用np.ctypeslib.ndpointer(dtype=np.float64,ndim=1,flags="C_CONTIGUOUS")直接將numpy中的數組聲明為C語言中的數組類型,最後調用時,直接將將numpy中的數組類型t2和y2傳到該函數中即可。相比於第1種方法,雖然在聲明時麻煩些,但在調用時可以直接使用numpy中的數組類型,相對來說要簡潔些,畢竟函數聲明只需聲明一次即可,但調用函數可能會在程序中出現多次。

完整的測試代碼

在測試程序中,使用了pyqtgraph庫畫兩種方法產生的正弦波形圖,不明白的可以翻看下前面的文章,專門介紹了該庫的畫圖方法。詳細可參考:Python使用pyqtgraph庫實現數據可視化之多條曲線繪製方法

完整的測試代碼如下圖所示:

運行結果如下圖所示:

從運行結果可以看出,兩種調用方法,都可以實現C語言數組與numpy數組之間數據正確的傳遞。相比來說,第2種方法更簡潔些。

歡迎加關注,共同交流。

相關焦點

  • Python使用ctypes模塊調用DLL函數之複數數組的參數傳遞
    這兒就涉及到了如何將C語言中的複數數組(Complex array)類型與Python中的數據類型進行交互的問題。在Python語言中,可以使用ctypes模塊調用其它如C++語言編寫的動態連結庫DLL文件中的函數,前面多篇文章中已經講了傳遞數值/指針/字符串參數、傳遞結構體參數、傳遞普通數組類型的例子,大家可以回看一下,這樣可以更好的理解本次要講的內容。
  • 如何獲取numpy數組的真實地址?如何與ctypes數組共享內存?
    02如何與ctypes庫創建的數組共享內存空間?對於Python編程人員來說,ctypes庫也是使用率比較高的一個庫,當調用第三方提供的動態庫連結庫函數時,它經常用於定義與C語言兼容的數據類型變量,作為Python語言與C語言進行數據交互的橋梁。
  • Python的武器庫05:numpy模塊(下)
    說到程式語言python,有一個著名的格言"餘生太短,只用python"。如果要分析為什麼會存在這麼一句格言?python的語法並不簡單,有複雜難懂的部分,之所以有這樣一句格言,是因為python中有很多強大的模塊,就像一個武器庫。
  • 加快Python算法的四個方法(二)Numba
    Numba是Python的即時編譯器,也就是說當你調用Python函數時,你的全部或部分代碼都會被計時轉換成為機器碼進行執行,然後它就會以你的本機機器碼速度運行,Numba由Anaconda公司贊助,並得到了許多組織的支持。使用Numba,你可以加速所有以集中計算的、計算量大的python函數(例如循環)的速度。它還支持numpy庫!
  • Python語言中使用array模塊實現動態數組的操作
    背景對於動態數組諸如創建、插入、刪除、查詢大小等操作,在C/C++語言中,可以使用標準庫中的vector類實現,而在python語言中,也同樣提供了內置的array模塊實現類似的功能。下面通過例子講解array模塊的常用操作。動態數組的創建創建方式為:array.array(typecode[, initializer]),第1個參數typecode定義了數組元素的類型,第2個可選參數給出了數組中的初始值。如下面的代碼創建了一個int型的包含3個元素的數組x,其初始值為分別為1、2、3。
  • Python Numpy-數組的常用函數
    日常使用numpy進行數據分析的時候,通常會使用模塊提供的函數,很大程度上方便了對於數據的操作。
  • Python數據分析之numpy數組全解析
    ndarray 中的每個元素在內存中使用相同大小的塊numpy數組創建 創建Numpy數組一般有三種方法:(1)通過傳入可待跌對象創建,我將之稱為基本方法(2)使用Numpy內部功能函數,內部方法(3)使用特殊的庫函數,特殊方法基本方法:np.array()基本方法是通過給numpy提供的一些函數中傳入可迭代對象來創建數組
  • Python的武器庫04:numpy模塊(上)
    說到程式語言python,有一個著名的格言"餘生太短,只用python"。如果要分析為什麼會存在這麼一句格言?python的語法並不簡單,有複雜難懂的部分,之所以又這樣一句格言,是因為python中有很多強大的模塊,就像一個武器庫。Python正式由於這些模塊的出現,只要引入這個模塊,調用這個模塊的集成函數,問題迎刃而解;不需要從頭開始,節省了大量的時間。
  • NumPy ndarray數組的創建
    +Tab鍵查看可使用的函數,如果對其中一些函數的使用不是很清楚,還可以在對應函數加上?,再運行,就可以很方便地看到如何使用函數的幫助信息。輸入np.然後按 Tab 鍵,將出現如下界面:圖1:查看 NumPy 可以使用的函數運行如下命令,便可查看函數 abs 的詳細幫助信息。np.abs?
  • Python入門教程(二):Numpy數組基礎
    import numpy as npnp.random.seed(0)  # 設置隨機種子數,保證程序執行時每次都可以生成同樣的隨機數組x1 = np.random.randint(10, size=6)  # 一維數組x2 = np.random.randint(10, size=(3, 4))  # 二維數組,創建三行四列的數組
  • NumPy的數組對象
    一、創建數組可以有多種方式創建NumPy數組:(1)使用NumPy的array函數從Python列表中創建數組,數組類型由列表中的數據類型確定;(2)使用NumPy的zeros函數創建數組元素全部為0的數組,默認情況下數組元素的類型為float64;(3)使用NumPy的ones函數創建數組元素全部為1的數組,默認情況下數組元素的類型為float64;(4)使用NumPy
  • Python數據分析類庫系列-Numpy之多維數組ndarray
    NumPy之於數值計算特別重要的原因之一,是因為它可以高效處理大數組的數據。 這是因為: NumPy是在一個連續的內存塊中存儲數據,獨立於其他Python內置對象。NumPy的C語言編寫的算法庫可以操作內存,而不必進行類型檢查或其它前期工作。
  • Python編程:如何規範numpy中數組元素的列印輸出格式
    引言對於Python語言開發者,如果你經常處理大量數據運算的話,numpy是一個必不可少的程序擴展庫,它支持大維度數組與矩陣運算,提供了非常豐富的數學運算函數,並且,相對於Python自身提供的列表類型,它在運算速度上有著無與倫比的優勢。
  • 不懂NumPy 算什麼 Python 程式設計師?|CSDN 博文精選
    了解 NumPy 之後,我才想明白當初磁層頂的三維模型之所以慢,是因為使用了 list(Python 數組)而不是 ndarray(NumPy 數組)存儲數據。有了 NumPy,Python 程式設計師才有可能寫出媲美 C 語言運行速度的代碼。熟悉 NumPy,才能學會使用 PyOpenGL / PyOpenCV / Pandas / Matplotlib 等數據處理及可視化的模塊。
  • 如果不懂Numpy,請別說自己是Python程式設計師
    了解 numpy之後,我才想明白當初磁層頂的三維模型之所以慢,是因為使用了 list(python 數組)而不是 ndarray(numpy 數組)存儲數據。有了 numpy,python 程式設計師才有可能寫出媲美 C 語言運行速度的代碼。
  • NumPy基礎教程,帶你玩轉多維數組
    Python 中的標準 type 函數同樣可以用於顯示數組類型,NumPy 有它自己的類型如:numpy.int32, numpy.int16, 和 numpy.float64,其中「int」和「float」代表數據的種類是整數還是浮點數,「32」和「16」代表這個數組的字節數(存儲大小)。ndarray.itemsize:數組中每個元素的字節存儲大小。
  • 定義只有一個數組成員的C語言結構體有什麼用?
    答案是肯定的,這樣做主要有兩個好處:一是便於值傳遞,二是便於後期擴展。方便的數組值傳遞看過我之前文章的讀者應該明白,調用C語言函數時,如果將數組作為參數傳遞給函數,那麼在被調用函數內部,數組常常會退化成指針。
  • 單片機的C語言中數組的用法
    數組是由具有相同類型的數據元素組成的有序集合。數組是由數組名來表示的,數組中的數據由特定的下標來唯一確定。引入數組的目的,是使用一塊連續的內存空間存儲多個類型相同的數據,以解決一批相關數據的存儲問題。數組與普通變量一樣,也必須先定義,後使用。數組在C51語言的地位舉足輕重,因此深入地了解數組是很有必要的。
  • Python學習第114課——numpy中ndarray的四則運算
    【每天幾分鐘,從零入門python編程的世界!】我們為什麼要學習numpy?numpy其實就是number+Python的簡寫,意思就是通過Python對數據進行處理。要對數據進行處理,就少不了最基本的加減乘除等操作。
  • 用R也可以跑Python了
    在R中導入一個python模塊您可以使用函數import()來導入特定的包或模塊。numpy <- import(「numpy」)使用numpy數組>首先建立一個簡單的numpy數組y <- array(1:4, c(2, 2))