ホームページ >バックエンド開発 >Python チュートリアル >PythonでDLLライブラリを呼び出す方法

PythonでDLLライブラリを呼び出す方法

爱喝马黛茶的安东尼
爱喝马黛茶的安东尼オリジナル
2019-06-13 11:51:1326783ブラウズ

場合によっては、Python の効率を補うために C が必要になりますが、実際のアプリケーションでは、何らかのデータ対話が必要になります。 Python の ctypes モジュールを使用すると、Windows DLL (Linux 上の so ファイルを含む) を簡単に呼び出すことができます。このモジュールについては、以下で詳しく説明します (Windows プラットフォームを例として説明します)。もちろん、その方法はすでに知っていると思います。 Windows 上で書き込みます。DLL は問題ありません。

PythonでDLLライブラリを呼び出す方法

ctypes ライブラリの紹介

from ctypes import *

既に DLL (名前は add.dll) があり、その DLL には cdecl (ここにあります) があると仮定します。 stdcallの呼び出し規約とcdeclの呼び出し規約で宣言されたエクスポート関数は、後述するPythonでロードする際に異なるロード関数を使用するため、呼び出し規約が強調されています)呼び出し規約のエクスポート関数Addが追加されています。

関連する推奨事項: 「Python ビデオ チュートリアル

Python ファイルの作成 DllCall.py テスト:

from ctypes import *  
dll = CDLL("add.dll")  
print dll.Add(1, 102)

結果: 103

上記は簡単な例です。呼び出しプロセスについて簡単に説明しましょう:
1. DLL のロード
上で述べたように、ロードするときは、呼び出そうとしている関数がどのような呼び出し規約に準拠しているかに基づいて行う必要があります。
stdcall 呼び出し規則: 2 つのロード メソッド

Objdll = ctypes.windll.LoadLibrary("dllpath")  
Objdll = ctypes.WinDLL("dllpath")

cdecl 呼び出し規則: 2 つのロード メソッド

Objdll = ctypes.cdll.LoadLibrary("dllpath")  
Objdll = ctypes.CDLL("dllpath")  
/*其实windll和cdll分别是WinDLL类和CDll类的对象。*/

2 もあります。dll 内のメソッドを呼び出します

In 1 DLL をロードすると、DLL オブジェクト (名前が Objdll であると仮定) が返され、このオブジェクトを使用して DLL 内のメソッドを呼び出すことができます。

例: dll に Add という名前のメソッドがある場合 (メソッドが stdcall で宣言されている場合、それが def ファイルまたは extern "C" で宣言されたエクスポート関数でない場合、コンパイラは変更を加えます。関数名。これに注意してください。理解できたと思います。)
Call: nRet = Objdll.Add(12, 15)、これで呼び出しが完了します。
非常に単純な呼び出しのようですね。見た目だけ見てはいけません。ははは、Add 関数が単純すぎるからです。この関数では、int 型のポインター (int*) を渡す必要があると仮定します。 )、呼び出される関数の 3 番目のパラメーターが int 型のポインターであると仮定して、ライブラリ キーワードで byref を使用して実装できます。

intPara = c_int(9)  
dll.sub(23, 102, byref(intPara))  
print intPara.value

char バッファ ポインタとバッファ長を渡したい場合は、少なくとも 4 つのメソッドがあります:

# 方法1  
szPara = create_string_buffer('/0'*100)  
dll.PrintInfo(byref(szPara), 100);  
print szPara.value    
# 方法2  
sBuf = 'aaaaaaaaaabbbbbbbbbbbbbb'  
pStr = c_char_p( )  
pStr.value = sBuf  
#pVoid = ctypes.cast( pStr, ctypes.c_void_p ).value  
dll.PrintInfo(pStr, len(pStr.value))  
print pStr.value    
# 方法3  
strMa = "/0"*20  
FunPrint  = dll.PrintInfo  
FunPrint.argtypes = [c_char_p, c_int]  
#FunPrint.restypes = c_void_p  
nRst = FunPrint(strMa, len(strMa))  
print strMa,len(strMa)    
# 方法4  
pStr2 = c_char_p("/0")  
print pStr2.value  
#pVoid = ctypes.cast( pStr, ctypes.c_void_p ).value  
dll.PrintInfo(pStr2, len(pStr.value))  
print pStr2.value

3. C の基本型と ctypes に実装された型マッピング テーブル
CTYPESデータ型Cデータタイプ
C_CHAR CHAR
C_SHORT SHORT
C_INT INT
C_LONG。
C言語の構造をPythonで実装するにはクラスを使用する必要があります。
4. DLL 内の関数はポインターを返します。
これは適切なプログラミング方法ではありませんが、この状況に対処する方法も非常に簡単で、実際には、すべてのアドレスが返され、対応する Python 型に変換され、value 属性を通じてアクセスされます。

pchar = dll.getbuffer()  szbuffer = c_char_p(pchar)  print szbuffer.value

5. C での構造体の型の扱い
なぜこれを別個に記述するのですか? これが最も面倒で複雑だからです。Python で c と同様の構造体を宣言するには、クラスを使用する必要があります。このクラスは Structure から継承する必要があります。

例:

Python コードは次のとおりです:

def CreateGUID():        
"""      
创建一个全局唯一标识符      
类似:E06093E2-699A-4BF2-A325-4F1EADB50E18      
NewVersion      
"""        
try:            
# dll path            
strDllPath = sys.path[0] + str(os.sep) + "createguid.dll"            
dll = CDLL(strDllPath)            
b = dll.newGUID()            
a = c_char_p(b)        
except Exception, error:            
print error            
return ""        
return a.value

例 2:

この例では、kernel32.dll の createprocessA 関数を呼び出して、メモ帳のプロセス。
rree

以上がPythonでDLLライブラリを呼び出す方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。