Python ctypes 加載 DLL(動態函式庫)

1. Python ctypes 提供三種動態函式庫的加載方式:

ctypes exports the cdll, and on Windows windll and oledll objects, for loading dynamic link libraries.

  1. cdll: cdll loads libraries which export functions using the standard cdecl calling convention.
  2. windll: windll libraries call functions using the stdcall calling convention.
  3. oledll: oledll also uses the stdcall calling convention, and assumes the functions return a Windows HRESULT error code.

2. Python ctypes 加載動態函式:

範例節錄自官網

windows:

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

linux:

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

3. Python ctypes 加載動態函式庫並呼叫其方法:

呼叫 windows 動態函式庫:

"""
Requirement:
  python: 3.x
  os: windows
"""

from ctypes import *

if __name__ == "__main__":
    msvcrt = cdll.msvcrt
    # msvcrt = CDLL("msvcrt")
    msvcrt.printf(b"Hello world")


4. C Calling Convention:

Calling Convention 描述如何以正確的方式調用函數,下面的例子解釋 cdecl 和 stdcall。

cdecl 參數由右向左壓入 stack,函數使用者需要清除 stack,為 x86 大多數 C Compiler 使用。

考慮一個 C 的 Function 宣告:

int Func (int arg1, int arg2, int arg3);

x86 assembly:

push arg3
push arg2
push arg1
call Func
add esp, 12

stack 是往下長所以增加 esp 等於是清除參數,add 12 to esp (stack 指針) 即是清除 stack 上的參數(每個參數占用 4 bytes)。

stdcall

廣範為 Win32API 所使用,參數壓入 stack 的順序和 cdecl 一樣但不用清除 stack。

考慮一個 C 的 Function 宣告:

int Func (int arg1, int arg2, int arg3);

x86 assembly:

push arg3
push arg2
push arg1
call Func
; no need to add esp

這兩種 Calling Convention 都使用 EAX 儲存 return 的值。

留言

熱門文章