DLL
name__内からPython
name__ファイルを使用する最も簡単な方法は何ですか?
具体的には、これをどのように行うことができますかwithout追加のラッパーC++
コードを記述して、機能をPython
name__に公開しますか?
ネイティブのPython
name__機能は、サードパーティのライブラリを使用するよりも強く推奨されます。
使いやすさのために、 ctypes が方法です。
次のctypesの例は、私が書いた実際のコード(Python 2.5)のものです。これは、あなたが尋ねたことをするために私が見つけた最も簡単な方法です。
import ctypes
# Load DLL into memory.
hllDll = ctypes.WinDLL ("c:\\PComm\\ehlapi32.dll")
# Set up prototype and parameters for the desired function call.
# HLLAPI
hllApiProto = ctypes.WINFUNCTYPE (
ctypes.c_int, # Return type.
ctypes.c_void_p, # Parameters 1 ...
ctypes.c_void_p,
ctypes.c_void_p,
ctypes.c_void_p) # ... thru 4.
hllApiParams = (1, "p1", 0), (1, "p2", 0), (1, "p3",0), (1, "p4",0),
# Actually map the call ("HLLAPI(...)") to a Python name.
hllApi = hllApiProto (("HLLAPI", hllDll), hllApiParams)
# This is how you can actually call the DLL function.
# Set up the variables and call the Python name with them.
p1 = ctypes.c_int (1)
p2 = ctypes.c_char_p (sessionVar)
p3 = ctypes.c_int (1)
p4 = ctypes.c_int (0)
hllApi (ctypes.byref (p1), p2, ctypes.byref (p3), ctypes.byref (p4))
ctypes
スタッフには、すべてのCタイプのデータ型(int
、char
、short
、void*
など)があり、値または参照で渡すことができます。また、特定のデータ型を返すこともできますが、私の例ではそれを行いません(HLL APIは、参照渡しの変数を変更することで値を返します)。
上記の特定の例では、IBMのEHLLAPIはかなり一貫したインターフェースです。
すべての呼び出しは4つのvoidポインターを渡します(EHLLAPIは4番目のパラメーター、int
へのポインターを介して戻りコードを送り返すので、戻り値の型としてint
を指定しますが、IBMのドキュメントに従って安全に無視できます) こちら 。つまり、関数のCバリアントは次のようになります。
int hllApi (void *p1, void *p2, void *p3, void *p4)
これにより、単一の単純なctypes
関数でEHLLAPIライブラリが提供するすべての処理を実行できますが、他のライブラリでは、ライブラリ関数ごとに個別のctypes
関数をセットアップする必要があります。
WINFUNCTYPE
からの戻り値は関数のプロトタイプですが、さらに多くのパラメーター情報を設定する必要があります(型に加えて)。 hllApiParams
の各タプルには、パラメーター「direction」(1 =入力、2 =出力など)、パラメーター名、およびデフォルト値があります-詳細については、ctypes
docoを参照してください
プロトタイプとパラメーターの情報を取得したら、関数を呼び出すPython "callable" hllApi
を作成できます。必要な変数(私の場合はp1
からp4
まで)を作成し、それらを使用して関数を呼び出すだけです。
このページ には、DLLファイルから関数を呼び出す非常に簡単な例があります。
完全を期すためにここで詳細を言い換えます:
PythonでDLL関数を呼び出すのは非常に簡単です。私は、2つの引数をとる
add
とsub
の2つの関数を備えた自作のDLLファイルを持っています。
add(a, b)
は2つの数値の加算を返しますsub(a, b)
は2つの数値の減算を返しますDLLファイルの名前は「demo.dll」になります
プログラム:
from ctypes import*
# give location of dll
mydll = cdll.LoadLibrary("C:\\demo.dll")
result1= mydll.add(10,1)
result2= mydll.sub(10,1)
print "Addition value:"+result1
print "Substraction:"+result2
出力:
Addition value:11
Substraction:9
ctypesを使用してdllにアクセスできます。チュートリアルを次に示します。
多分Dispatch
で:
from win32com.client import Dispatch
zk = Dispatch("zkemkeeper.ZKEM")
Zkemkeeperがシステムに登録されているDLLファイルの場合...その後、関数を呼び出すだけで関数にアクセスできます。
zk.Connect_Net(IP_address, port)
ctypesは最も簡単に使用できますが、(誤)使用するとPythonがクラッシュしやすくなります。あなたが何かを素早くやろうとしていて、あなたが注意しているなら、それは素晴らしいことです。
チェックアウトすることをお勧めします Boost Python 。はい、C++コードを作成してC++コンパイラを用意する必要がありますが、実際に使用するためにC++を学ぶ必要はなく、無料で(ビールのように)入手できます MicrosoftのC++コンパイラ 。
shared library
を構築し、Python
を使用してctypes
の下で使用する方法について、完全に機能する例を示します。 Windows
の場合を検討し、DLLs
を扱います。次の2つの手順が必要です。
私が検討するshared library
は以下であり、testDLL.cpp
ファイルに含まれています。唯一の関数testDLL
は、単にint
を受け取り、それを出力します。
#include <stdio.h>
extern "C" {
__declspec(dllexport)
void testDLL(const int i) {
printf("%d\n", i);
}
} // extern "C"
コマンドラインからVisual Studio
でDLL
をビルドするには
"C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\Tools\vsdevcmd"
インクルードパスを設定して実行する
cl.exe /D_USRDLL /D_WINDLL testDLL.cpp /MT /link /DLL /OUT:testDLL.dll
dLLをビルドします。
DLL
を構築するまたは、次のようにVisual Studio
を使用してDLL
をビルドできます。
Pythonで、次の操作を行います
import os
import sys
from ctypes import *
lib = cdll.LoadLibrary('testDLL.dll')
lib.testDLL(3)