web-dev-qa-db-ja.com

PythonのDLLファイルを使用するにはどうすればよいですか?

DLLname__内からPythonname__ファイルを使用する最も簡単な方法は何ですか?

具体的には、これをどのように行うことができますかwithout追加のラッパーC++コードを記述して、機能をPythonname__に公開しますか?

ネイティブのPythonname__機能は、サードパーティのライブラリを使用するよりも強く推奨されます。

166
Tom Hennen

使いやすさのために、 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タイプのデータ型(intcharshortvoid*など)があり、値または参照で渡すことができます。また、特定のデータ型を返すこともできますが、私の例ではそれを行いません(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まで)を作成し、それらを使用して関数を呼び出すだけです。

140
paxdiablo

このページ には、DLLファイルから関数を呼び出す非常に簡単な例があります。

完全を期すためにここで詳細を言い換えます:

PythonでDLL関数を呼び出すのは非常に簡単です。私は、2つの引数をとるaddsubの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

60
atul

ctypesを使用してdllにアクセスできます。チュートリアルを次に示します。

http://docs.python.org/library/ctypes.html#module-ctypes

7
monkut

多分Dispatchで:

from win32com.client import Dispatch

zk = Dispatch("zkemkeeper.ZKEM") 

Zkemkeeperがシステムに登録されているDLLファイルの場合...その後、関数を呼び出すだけで関数にアクセスできます。

zk.Connect_Net(IP_address, port)
5
Carlos Gomez

ctypesは最も簡単に使用できますが、(誤)使用するとPythonがクラッシュしやすくなります。あなたが何かを素早くやろうとしていて、あなたが注意しているなら、それは素晴らしいことです。

チェックアウトすることをお勧めします Boost Python 。はい、C++コードを作成してC++コンパイラを用意する必要がありますが、実際に使用するためにC++を学ぶ必要はなく、無料で(ビールのように)入手できます MicrosoftのC++コンパイラ

3
David Nehme

DLLを構築し、ctypesを使用してPythonの下にリンクします

shared libraryを構築し、Pythonを使用してctypesの下で使用する方法について、完全に機能する例を示します。 Windowsの場合を検討し、DLLsを扱います。次の2つの手順が必要です。

  1. コマンドラインまたはIDEからVisual Studioのコンパイラを使用してDLLをビルドします。
  2. Ctypesを使用して、DLLの下のPythonをリンクします。

共有ライブラリ

私が検討するshared libraryは以下であり、testDLL.cppファイルに含まれています。唯一の関数testDLLは、単にintを受け取り、それを出力します。

#include <stdio.h>
​
extern "C" {
​
__declspec(dllexport)
​
void testDLL(const int i) {
    printf("%d\n", i);
}
​
} // extern "C"

コマンドラインからDLLを構築する

コマンドラインからVisual StudioDLLをビルドするには

"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をビルドします。

IDEからDLLを構築する

または、次のようにVisual Studioを使用してDLLをビルドできます。

  1. ファイル->新規->プロジェクト;
  2. インストール済み->テンプレート-> Visual C++-> Windows-> Win32-> Win32Project;
  3. 次;
  4. アプリケーションタイプ-> DLL;
  5. 追加オプション->空のプロジェクト(選択);
  6. 追加オプション->プリコンパイル済みヘッダー(選択解除);
  7. プロジェクト->プロパティ->構成マネージャー->アクティブなソリューションプラットフォーム:x64;
  8. プロジェクト->プロパティ->構成マネージャー->アクティブなソリューション構成:リリース。

PythonでのDLLのリンク

Pythonで、次の操作を行います

import os
import sys
from ctypes import *

lib = cdll.LoadLibrary('testDLL.dll')

lib.testDLL(3)
0
JackOLantern