光学設計とその周辺、そしてたまに全く関係ないやつ

学んだことを書き留めていきたいと思いますが、ありふれたことを書いても人類の進歩に貢献しないので、専門的な事柄をメインにしたいと思います。なお私の専門とは光学設計とか画像処理とかです。

Visual Studio上でPython用のC++のDLLのデバッグ設定方法

Pythonは使いやすい言語だけどスクリプト言語特有の遅さというのはどうしてもあるため, 部分的にC++で作成したDLLを呼び出して処理させることをよくするのですが, このときVisual StudioでDLLのデバッグをする方法を調べてたので忘備録もかねて記事にまとめます.

参考にしたのは以下のMSのページです.
docs.microsoft.com


実行環境は以下の通り
Visual Studio 2019
Python 3.7

サンプルコードは以下の通り.
DLL(debugtest)の内容は単に配列を受け取ってその和を返すだけ. それをpython(pytest.py)で呼び出す. 配列の渡し方は以下のリンク先を参照
tangerina.jp


debugtest.cpp

#include "debugtest.h"

double ReturnArySum(int n, double* data)
{
    double retval = 0;
    for (int i = 0; i < n; i++) {
        retval += data[i];  //ここでブレークポイント指定
    }
    return retval;
}

debugtest.h

#pragma once

#ifdef DLLTEST_EXPORTS
#define DLLTEST_API extern "C" __declspec(dllexport)
#else
#define DLLTEST_API extern "C" __declspec(dllimport)
#endif // DLLTEST_EXPORTS

DLLTEST_API double ReturnArySum(int, double*);

pytest.py

from ctypes import *

# load DLL
dll = cdll.LoadLibrary("debugtest.dll")
ReturnArySum=dll.ReturnArySum
ReturnArySum.argtypes = [c_int, c_void_p]
ReturnArySum.restype =c_double

PyAry=[1.5,2,10.1] #DLLに渡す配列
ARRAY = c_double * len(PyAry)
array = ARRAY(*PyAry)
print(ReturnArySum(len(PyAry), byref(array))) #13.6と表示

さてvisual studioでの設定はまずソリューションファイルにdllとpythonそれぞれのプロジェクトを以下のように追加する

次にpython側の設定でプロパティを開き、デバッグタブの「ネイティブ コードのデバッグを有効にする」にチェックする

今度はVisual Studioデバッグタブからプロセスにアタッチを選択, そして表示されるウインドウの選択ボタンから以下の通りネイティブとpythonを選択する.

最後にC++側の設定としてC++プロジェクトのプロパティを開き、その中のデバッグタブから起動するデバッガーとしてPython/Native Debugging(Python/ネイティブ デバッグ)を選択してOKする. なおこの時ビット設定を使用するPythonに合わせる. 今どきは64bit環境であることが多いと思うので画面のプラットフォームのところを64にする。

設定は以上. 試しにcppファイル中にブレークポイントを指定して、visual studioからpythonを実行すると以下のようにちゃんとブレークしてくれました. ただしやたらと遅い...のは仕様だろうか.