試したサンプル
pythonからDLL(C++)をコールして文字列を受け渡す。
また、DLLで受け取った文字列をメッセージボックスで表示する。
環境
- Windows10pro(64bit)
- Python3.6.2 64bit
- Microsoft Visual C++ 2017 Community
※DLLの作成方法は先人の記事をご参考↓
https://qiita.com/tibigame/items/da0e50f59fb0b9fac540
C++コード(DLL)
testDll.cpp
// testDll.cpp : DLL アプリケーション用にエクスポートされる関数を定義します。
//
#include "stdafx.h"
#include <tchar.h>
extern "C" __declspec(dllexport) void __stdcall mbox(LPCTSTR in, LPTSTR out) {
_tcscpy_s(out, 32, _T("戻り値:"));
_tcscat_s(out, 32, in);
::MessageBox(NULL, in, _T("test"), MB_OK);
}
Pythonコード
※ロードするDLLがマルチバイト文字セットを使用している場合
test_call_multibyte_dll.py
# -*- coding: utf-8 -*-
import ctypes
import sys
user32 = ctypes.cdll.LoadLibrary("testDll")
user32.mbox.restype = ctypes.c_void_p
user32.mbox.argtypes = (
ctypes.c_char_p,ctypes.c_char_p
)
print('defaultencoding:'+sys.getdefaultencoding())
outmsg = ctypes.create_string_buffer(32)
inmsg = 'DLLコールテスト'
user32.mbox(inmsg.encode('mbcs'), outmsg);
print(outmsg.value.decode('mbcs'))
※ロードするDLLがUnicode文字セットを使用している場合
test_call_unicode_dll.py
# -*- coding: utf-8 -*-
import ctypes
import sys
user32 = ctypes.cdll.LoadLibrary("testDll")
user32.mbox.restype = ctypes.c_void_p
user32.mbox.argtypes = (
ctypes.c_wchar_p,ctypes.c_wchar_p
)
print('defaultencoding:'+sys.getdefaultencoding())
outmsg = ctypes.create_unicode_buffer(32)
inmsg = 'DLLコールテスト'
user32.mbox(inmsg, outmsg);
print(outmsg.value)
実行結果
defaultencoding:utf-8
戻り値:DLLコールテスト
ポイント
-
argtypes
でコールするDLL関数の引数の型に合わせて設定する - DLLからの受取用のバッファを
ctypes.create_xxxx_buffer()
で設定する(xxxxは文字設定に応じたもの) - マルチバイト文字列の場合は、引数を文字列→バイト列に変換して関数をコールする