本日は Python の技術調査枠です。
Python から DLL を利用する手順について記事にします。
DLLファイルの作成
最初に Python から呼び出す DLL ファイルを Visual Studio 2017 を利用して作成します。
[ダイナミック リンク ライブラリ]のプロジェクトを作成します。
今回、プロジェクト名を TestLib としました。
プロジェクトが新規作成されました。
外部から参照する関数のエクスポート定義を行う必要がありますので、ヘッダーファイルを作成します。
作成されたヘッダーファイルを TestLib.h と名付け、以下の定義を追加しました。
#ifdef TESTLIB_EXPORTS #define TESTLIB_API extern "C" __declspec(dllexport) #else #define TESTLIB_API extern "C" __declspec(dllimport) #endif
「TESTLIB」の部分は英大文字のプロジェクト名で定義します。
プロジェクトを DLL としてコンパイルする際に Visual Studio が[TESTLIB_EXPORTS]を定義します。
これにより、コンパイル時に __declspec(dllexport) の定義が選択され、DLL 外部から対象の関数が参照できるようになります。
今回は Python 側で ctypes を使って外部関数を呼び出します。
この場合、使用する関数が C リンケージに登録されている必要があります。
デフォルトでは C++ リンケージに登録されるため、シンボル名が変更されてしまいます。
これに対処するため、extern "C" を利用して C リンケージにも関数を登録しています。
qiita.com
この TESTLIB_API のエクスポート定義を利用して2つの int 値を足し算する SumInt 関数を宣言しました。
TESTLIB_API int SumInt(int, int);
次に SumInt 関数の実装を行います。
プロジェクト作成時に生成された TestLib.cpp を開き、以下のコードを追加しました。
#include "TestLib.h" int SumInt(int x, int y) { return x + y; }
これで DLL の実装は完了です。ビルド設定を[Release][x64]に変更します。
ビルドのビット設定は Python のビット数に合わせる必要があります。
著者環境では 64 bit の Python を利用するため、[x64]を選択しています。
メニューから ビルド -> ソリューションのビルド を実行します。
ビルドを完了すると TestLib.dll が出力されます。
Ptyonの実装
Python から DLL の外部関数を呼び出すため、ctypes を利用します。
docs.python.org
ctypes で DLL を読み込む場合、以下のようにスクリプトを実装します。
from ctypes import * dll = cdll.LoadLibrary("TestLib.dll")
SumInt 関数を呼び出し、その結果を print 出力するスクリプトを作成しました。
・dllAccessTest.py
# ctypesインポート from ctypes import * # DLLをロードする dll = cdll.LoadLibrary("TestLib.dll") # SumInt関数を呼び出して結果を出力する print(dll.SumInt(3, 2))
スクリプトと同じディレクトリに TestLib.dll を配置し、PowerShell を開きます。
以下のコマンドを実行して、スクリプトを実行します。
> py .\dllAccessTest.py
DLL 内の SumInt 関数が呼び出され、5 が戻り値として print 出力されれば成功です。