歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Python調用C模塊(二): ctypes

Python調用C模塊(二): ctypes

日期:2017/3/1 10:29:42   编辑:Linux編程
前面理了理 用C擴展Python的傳統方法(見 http://www.linuxidc.com/Linux/2012-02/55038.htm),接下來學習一下 ctypes

ctypes 這個東西到底怎麼樣的,網絡上搜搜資料:似乎有的人對的評價很高,認為很好;有的人則不以為然,認為不怎麼方便(特別頭文件的東西要實現一遍)。

cdll、windll、oledll

ctypes 會導出 cdll,在windows平台下還會導出 windll 和 oledll。

這三個可以用於導入動態鏈接庫,那麼區別是什麼呢?

  • cdll 載入 導出函數 符合cdecl調用規范的庫
  • windll 載入 導出函數 符合 stdcall 調用規范的庫,
  • oledll 也使用 stdcall 調用規范,並假設函數返回Windows的HRESULT錯誤碼(用於在WindowsError這個Python異常)

導入鏈接庫

Windows下

Windows 通常使用".dll"作為動態鏈接庫的擴展名,處理起來比較簡單。

直接使用 cdll、windll或oledll的屬性操作

>>> from ctypes import *
>>> print windll.kernel32
<WinDLL 'kernel32', handle ... at ...>
>>> print cdll.msvcrt
<CDLL 'msvcrt', handle ... at ...>

Linux下

Linux上需要指定包含擴展名的文件名來載入動態庫,所以屬性存取方式就失效了。

  • 使用 LoadLibrary

  • 或者創建CDLL的實例

>>> cdll.LoadLibrary("libc.so.6")
<CDLL 'libc.so.6', handle ... at ...>
>>> libc==CDLL("libc.so.6")
>>> libc
<CDLL 'libc.so.6', handle ... at ...>

查找鏈接庫

>>> from ctypes.util import find_library 
>>> find_library("m")
>>> printf = ctypes.CDLL(find_library("c")).printf

類型

  • c_char c_wchar c_byte ... c_int ... c_double 等值類型,都是可變的
  • c_char_p c_wchar_p c_void_p 指針類型,需要小心

>>> s="Hello, world"
>>> c_s=c_char_p(s)

這樣賦值,由於python的string是不可變的,這樣其實是地址變了。

要用 create_string_buffer 或 create_unicode_buffer

Copyright © Linux教程網 All Rights Reserved