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


186

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

具体的には、機能を公開するための追加のラッパーコードを記述せずに、これをどのように行うことができますか?C++Python

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


@Remuze間違った質問にタグ付けしたり、間違った答えでタグ付けしたりしましたか?どちらもpythonですが、まったく同じである理由はわかりません(そして、過去のある時点で改訂履歴を調べて、どこか近づいていないことを確認しました)
2016

@foon hmmmはい、申し訳ありません。別の質問に重複としてフラグを付け、これを入れます:)私はそれらがどれほど似ているかを示していると思います!
Trev Davies

回答:


154

使いやすくするために、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つの、ボイドポインタを渡す(EHLLAPIは、第四パラメータを通じてへのポインタ戻りコードバックを送信しint、私が指定している間、そうするintIBMのマニュアルに従って戻り値の型として、私は安全にそれを無視することができます)ここに。つまり、関数のCバリアントは次のようになります。

int hllApi (void *p1, void *p2, void *p3, void *p4)

これによりctypes、EHLLAPIライブラリーが提供するすべてのことを実行できる単一の単純な関数になりますが、他のライブラリーでは、ctypesライブラリー関数ごとに別個の関数をセットアップする必要がある可能性があります。

からの戻り値WINFUNCTYPEは関数プロトタイプですが、(型に加えて)追加のパラメーター情報を設定する必要があります。の各タプルにhllApiParamsは、パラメーター「方向」(1 =入力、2 =出力など)、パラメーター名、およびデフォルト値があります-詳細についてはctypesdocoを参照してください

プロトタイプとパラメーター情報を取得したらhllApi、関数を呼び出すための「呼び出し可能」なPythonを作成できます。必要な変数を作成し(私の場合はp1スルーp4)、それらを使用して関数を呼び出すだけです。


1
こんにちは、誰かがここで返信してからは長い時間がかかるかもしれませんが、私はこのプログラムを私のプログラムで正確に機能させるために何かを知りたいと思っていました。これの「HLLAPI」とは何ですか?また、「void BoxProperties(double L、double H、double W、double&A、double&V);」という関数を使用してdllにアクセスする場合も、それを機能させるために、上記のコードにどのような変更を加える必要があるか教えていただけますか 乾杯。
Neophile

4
正確には何をしhllApiParamsますか?それらのタプルのポイントは何ですか?この例のいくつかをドキュメントと一致させることは困難です。
Jonathon Reinhart、2012年

1
@JonathonReinhart、私は具体的な例を少し具体化して、下部にテキストをいくつか示しました。うまくいけば、それはそれを少し良く説明します。そうでない場合は、お知らせください。再試行します:-)
paxdiablo

1
素晴らしい答え、6年後の多くを助けます:)もしそれができたら+100を入れたでしょう!
ボーベル大佐、2015

1
これは、ctypesの初心者の観点からは非常に混乱します。
DuckPuncher

69

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

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

PythonでDLL関数を呼び出すのは非常に簡単です。私は2つの機能を備えた自作のDLLファイルを持っていますaddし、sub二つの引数を取るいます。

add(a, b)2つの数値の加算を返します2つの数値の
sub(a, b)減算を返します

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


2
この回答のリンクは壊れています。
Kaliber64 2013

10
リンクが機能しない場合でも心配ありません。直接コピーして貼り付けてください。情報を見逃していません。
湿地


6

多分Dispatch

from win32com.client import Dispatch

zk = Dispatch("zkemkeeper.ZKEM") 

ここで、zkemkeeperはシステム上の登録済みDLLファイルです...その後、関数を呼び出すだけで関数にアクセスできます。

zk.Connect_Net(IP_address, port)

私はこのzkemkeeper.ZKEMに取り組んでいます。Pythonでリアルタイムイベントを取得する方法を知っていますか?
サムZiggler

4

DLLをビルドし、Pythonでctypesを使用してリンクする

私は建物どのように完全に働いた例を提示shared libraryし、下にそれを使用してPythonによるctypesWindows事情を考慮して対処しDLLsます。2つのステップが必要です。

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

共有ライブラリ

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を構築する

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

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

建物DLLIDEから

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

  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)

DLLがPythonパッケージにある場合はどうなりますか?どうすればアクセスできますか?
Decanza

3

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

Boost Pythonをチェックすることをお勧めします。はい、それはあなたがいくつかのC ++コードを書いてC ++コンパイラを持っていることを必要とします、しかしそれを実際に使うためにC ++を学ぶ必要はありません、そしてあなたはMicrosoftから無料の(ビールのように)C ++コンパイラを得ることができます


0

DLLのタイプがCOMライブラリの場合は、pythonnetを使用できます。

pip install pythonnet

次に、Pythonコードで、次のことを試してください

import clr
clr.AddReference('path_to_your_dll')

次に、DLLのクラスに従ってオブジェクトをインスタンス化し、その中のメソッドにアクセスします。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.