14
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Pybind11でC++関数をPythonから実行する(Windows & Visual Studio Codeな人向け) デバッグ編

Last updated at Posted at 2021-01-15

環境構築編に続き、デバッグの方法を説明します。

1. 呼び出し用スクリプトの準備

ビルドが終わった段階のフォルダーのルートに、main.pyを追加します。

フォルダー構成
project_root
├ build
│ └ Debug
│   └ cmake_example.cp37-win_amd64.pyd
├ pybind11
├ src
│ └main.cpp
├ CMakeLists.txt
└ main.py              ←これを追加

main.pyはC++関数を呼び出すスクリプトで、内容は次のとおり:

main.py
import os
from build.Debug.cmake_example import add


print(f'PID: {os.getpid()}') # アタッチしてデバッグするためのもの

a = add(1,2)
print(a)

2. C++拡張のデバッグ

はじめにC++関数部分のみのデバッグ方法を説明します。ブレークポイントを設定できるのはC++のみです。

2.1. デバッグ用の構成の作成

コマンドパレット(Ctrl+p)からDebug: Open launch.jsonと入力し、C++ (Windows)を選択。launch.jsonが開かれる:

launch.json
{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(Windows) 起動",
            "type": "cppvsdbg",
            "request": "launch",
            "program": "プログラム名を入力してください (例: ${workspaceFolder}/a.exe)",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": false
        }
    ]
} 

上記を修正。"program"部分にPythonのパスを、"args"の括弧内に"${file}"を入力する:

launch.json(修正例)
        {
            "name": "(Windows) 起動",
            "type": "cppvsdbg",
            "request": "launch",
            "program": "c:/programdata/anaconda3/python.exe", //ここと
            "args": ["${file}"],                      //ここ
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": false
        }

注意: "stopAtEntry"の値はfalseのままにすること。trueにすると、Pythonの実行ファイル(python.exe)をデバッグしようとしてしまい、Unable to open 'python.c'というエラーで止まるため。

2.2. デバッグの実行

main.creturn i + j;の部分にブレークポイントを設定し、main.pyを開いた状態でデバッグを実行(F5)します。問題なければブレークポイントで止まるはずです。

3. PythonとC++拡張の混合モードでのデバッグ

今度はPythonとC++拡張の同時デバッグ方法を説明しす。PythonとC++の両方にブレークポイントを設定できます。

Pythonのデバッガーを起動して、そこにC++のデバッガーをアタッチすることで実現します。こちらで非常にわかりやすく解説されていますので、是非ご覧ください。

3.1. デバッグ用の構成の作成

Python用、C++用の二つの構成を追加します。

  • C++: コマンドパレットから、Debug: Select and Start Debugging->構成の追加...->C/C++: (Windows) 接続で追加
  • Python: main.pyを開いて、コマンドパレットからDebug: Select and Start Debugging->構成の追加...->Python->Python File
    で追加

launch.jsonに次が追加されます:

launch.json
        {
            "name": "Python: Current File",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "console": "integratedTerminal"
        },
        {
            "name": "(Windows) 接続",
            "type": "cppvsdbg",
            "request": "attach",
            "processId": "${command:pickProcess}"
        }

3.2. デバッグの実行

main.pya = add(1,2)main.creturn i + j;にブレークポイントを設定します。
デバッグを実行しましょう。まずはPythonから。main.pyを開き、コマンドパレット->Debug: Select and Start Debugging->Python: Current Fileで実行すると、先ほどのブレークポイントで止まります。また、ターミナルにプロセスのIDがPID: xxxxと表示されます(xxxxは数字)。
次にC++。コマンドパレット->Debug: Select and Start Debugging->(Windows) 接続で開始します。"アッタッチするプロセスを選択する"と表示されますので、先ほどのPIDを入力すれば準備完了です。
main.pyに戻り、ステップ実行(F10)すればC++のブレークポイントで止まります。
Python.jpg

4. (おまけ1)Jupyterとの連携

main.pyと同様の内容を.ipynbファイルで実行し、そのPIDにアタッチすれば、JupyterとC++のデバッグを連携できます。これは便利かも。
Jupyter.jpg

5. (おまけ2)Excel VBAとPythonとC++拡張の混合デバッグ

ExcelからPythonを呼び出して、そのPythonからC++を呼び出すことがあるかもしれません。各種設定をExcelのシートに入力して、そこからPythonを呼び出して計算して出力するけれど、計算負荷が高そうな(or 既存のC++資産を活かしたい)時にC++を使うという感じで。Excelはフロントエンド、Pythonは全体的な処理と出力、C++は計算を担当する使い方です。

そんんことしねーよという声も聞こえてきましたが、引き続き今回のコードで説明します。

5.1. Excelファイルの準備等

Excel VBAから利用&デバッグ可能な次のファイルmain_xw.pyを準備します。

main_xw.py
import os
from build.Debug.cmake_example import add
import xlwings as xw


@xw.func
def xw_add(a, b):
    return add(int(a), int(b))


if __name__ == '__main__':
    print(f'PID: {os.getpid()}')
    xw.serve()

Excel VBAとの連携にはxlwingsを使用します。同じフォルダーにmain_xw.xlsmファイルを置き、リボンxlwingsImport Functionsをクリックし、VBエディター(Alt+F11)の参照設定でxlwingsにチェックを入れます。適当なセルでxw_add関数が使えれば、呼び出し元Excelファイルの準備はOKです。(xlwingsの詳しい説明はこちらをご覧ください。)

(xlwingsは私の推しメンなんですが、残念なことにopenpyxlに比べて知名度がいまいちです(本が売っていない!)。これを機に是非使ってみてください。ドキュメントもしょぼいですが日本語化されています。)

5.2. デバッグの実行

ブレークポイントは以下の3か所に設定します:

  • VBA: 標準モジュールxlwings_udfs内のどこか
  • Python: main_xw.pyreturn add(int(a), int(b))
  • C++: main.creturn i + j;

デバッグを実行しましょう。3.2.と同様に、main.pyを開き、Python: Current Fileを実行し、(Windows) 接続でアタッチします。xlwingsのデバッグ用のサーバーも立ち上がっているので、ExcelのxliwngsリボンでDebug UDFsにチェックを入れれば準備完了です。

適当なセルに=xw_add(1,2)と入力すれば、VBAからPythonに、PythonからC++にブレークポイントを移動しながら実行することができます:
xlwings.jpg

6. トラブルシューティング

(今後追記予定)

参考

以下を参考にさせていただきました。

デバッグ方法

14
21
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?