Following Environment Construction, we will explain how to debug.
Add main.py
to the root of the folder when the build is finished.
Folder structure
project_root
├ build
│ └ Debug
│ └ cmake_example.cp37-win_amd64.pyd
├ pybind11
├ src
│ └main.cpp
├ CMakeLists.txt
└ main.py ← add this
main.py
is a script that calls a C ++ function and contains:
main.py
import os
from build.Debug.cmake_example import add
print(f'PID: {os.getpid()}') #For attaching and debugging
a = add(1,2)
print(a)
First, I will explain how to debug only the C ++ function part. Breakpoints can only be set in C ++.
Enter Debug: Open launch.json
from the command palette (Ctrl + p
) and select C ++ (Windows)
. launch.json is opened:
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)Start-up",
"type": "cppvsdbg",
"request": "launch",
"program": "Please enter the program name(Example: ${workspaceFolder}/a.exe)",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false
}
]
}
Fixed the above. Enter the Python path in the " program "
part and the " $ {file} "
in parentheses for the " args "
:
launch.json (correction example)
{
"name": "(Windows)Start-up",
"type": "cppvsdbg",
"request": "launch",
"program": "c:/programdata/anaconda3/python.exe", //here
"args": ["${file}"], //here
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false
}
** Note: Leave the value of " stopAtEntry "
as false
. ** If set to true
, it will try to debug the Python executable file (python.exe) and will stop with the error Unable to open'python.c'
.
Set a breakpoint in the return i + j;
part of main.c
and execute debugging (F5
) with main.py
open. If all goes well, it should stop at the breakpoint.
Now let's see how to debug Python and C ++ extensions at the same time. You can set breakpoints in both Python and C ++.
This is achieved by launching the Python debugger and attaching the C ++ debugger to it. It is explained in a very easy-to-understand manner in here, so please have a look.
Add two configurations, one for Python and one for C ++.
--C ++: From the command palette, Debug: Select and Start Debugging
-> Add configuration ...
-> C/C ++: (Windows) Connection
--Python: Open main.py
and from the command palette Debug: Select and Start Debugging
-> Add configuration ...
-> Python
-> Python File
Add with
The following is added to launch.json
:
launch.json
{
"name": "Python: Current File",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal"
},
{
"name": "(Windows)Connection",
"type": "cppvsdbg",
"request": "attach",
"processId": "${command:pickProcess}"
}
Set breakpoints at a = add (1,2)
in main.py
andreturn i + j;
in main.c
.
Let's debug. First from Python. If you open main.py
and run it in the command palette-> Debug: Select and Start Debugging
-> Python: Current File
, it will stop at the breakpoint you just saw. Also, the terminal will display the process ID as * PID: xxxx * (* xxxx * is a number).
Then C ++. Start with Command Palette-> Debug: Select and Start Debugging
-> (Windows) Connection
. The message "Select the process to attach" will be displayed. Enter the PID and you are ready to go.
Go back to main.py
and step through (F10) to stop at a C ++ breakpoint.
You can work with Jupyter and C ++ debugging by running the same content as main.py
in a .ipynb
file and attaching it to that PID. This may be convenient.
You might call Python from Excel and then call C ++ from that Python. I input various settings into an Excel sheet, call Python from there, calculate and output, but when the calculation load seems to be high (or I want to utilize existing C ++ assets), I feel like using C ++. Excel is the front end, Python is the overall processing and output, and C ++ is the calculation.
I've heard some people say that it's not good, but I will continue to explain it in this code.
Prepare the following file main_xw.py
that can be used & debugged from Excel VBA.
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()
Use xlwings to link with Excel VBA. Place the main_xw.xlsm
file in the same folder, click Import Functions
on the ribbon xlwings
, and check xlwings
in the reference settings of the VB editor (Alt + F11). If you can use the xw_add
function in the appropriate cell, the calling Excel file is ready. (See here for a detailed explanation of xlwings.)
(Xlwings is my favorite, but unfortunately it's not as well known as openpyxl (books aren't for sale!). Please take this opportunity to use it. The documentation is also [Short but Japanese (https://qiita.com/k_maki/items/e20a3225428e580c2072).)
Set breakpoints in three places:
--VBA: Somewhere in the standard module xlwings_udfs
--Python: return add (int (a), int (b))
of main_xw.py
--C ++: return i + j;
in main.c
Let's debug. As in 3.2., open main.py
, run Python: Current File
, and attach with a (Windows) connection
. The server for debugging xlwings is also running, so check Debug UDFs
in the xliwngs ribbon of Excel and you're ready to go.
You can run it while moving breakpoints from VBA to Python and from Python to C ++ by typing = xw_add (1,2)
in the appropriate cell:
(Scheduled to be added in the future)
I referred to the following.