Communication between 2 different language isn’t so easy.
It’s often possible to find libraries to help us achieve this behaviour.
That’s what we are going to see in this Boost.Python tutorial for Windows.
Let’s get started.
First of all
We need to install Python 3 and Boost on your computer.
So in order to have the exact same software and libraries installed in the exact same locations, I suggest to follow the 2 following tutorials:
For Visual Studio 2017 and MSVC 141, install Python 3.7 and Boost 1.71.0 for MSVC 141.
For Visual Studio 2019 and MSVC 142, install Python 3.9 and Boost 1.77.0 for MSVC 142.
Creating a DLL with Visual Studio
Let’s now create a new project:
From Visual Studio > File > New > Project… > Installed > Visual C++ > Windows Desktop > Dynamic-Link Library (DLL).
Then:
- Name: badprog_lib
- Location: C:\dev\c++\py
- Let unchecked the Create directory for solution option (don’t need for this tutorial).
Click OK.
So you have now the following directory:
- C:\dev\c++\py\badprog_lib
With classic files generated by Visual Studio like:
- C:\dev\c++\py\badprog_libbadprog_lib.cpp
- C:\dev\c++\py\badprog_libbadprog_lib.sln
- And so on.
Setting the Visual Studio project platform
First thing is now to change the project platform in the Configuration manager:
From Visual Studio> Select (right click mouse) the badprog_lib project > Properties… > On upper right click the Configuration Mananger… push button > Change Active solution platform from x86 to x64 > Close.
Then still in the badprog_lib Property Pages, at top center, change the Platform from Win32 to x64 (if not automatically updated).
So you have now:
- Configuration: Debug
- Platform: x64
Then click OK.
You can stay in Debug mode or change it to Release (it won’t change anything for our tutorial).
Setting Visual Studio include paths for Boost and Python
First let’s set the includes.
From Visual Studio > Select the badprog_lib.cpp file.
Then right click mouse > Properties… > Configuration Properties > C/C++ > General > Additioal Include Directories > Edit > Add the 2 following lines:
For Visual Studio 2017 (and MSVC 141) you need to install Python 3.7:
- C:\soft\boost_1_71_0
- C:\soft\python37\include
For Visual Studio 2019 (and MSVC 142) you need to install Python 3.9:
- C:\soft\boost_1_77_0
- C:\soft\python39\include
Then OK > Apply > OK.
Setting Visual Studio library paths for Boost and Python
We’ve now to set the libraries.
Same thing but with the linker:
From Visual Studio > Right click the badprog_lib project > Properties > Configuration Properties > Linker > General> Additioal Library Directories > Edit > Add the 5 following lines:
For MSVC 141 (2017)
- C:\soft\boost_1_71_0\lib64-msvc-14.1
- C:\soft\python37\DLLs
- C:\soft\python37\Lib
- C:\soft\python37\libs
- C:\soft\python37\tcl
For MSVC 142 (2019)
- C:\soft\boost_1_77_0\lib64-msvc-14.2
- C:\soft\python39\DLLs
- C:\soft\python39**\Lib**
- C:\soft\python39\libs
- C:\soft\python39\tcl
Then OK > Apply > OK.
Let’s code a bit
It’s now time to code our Dinamic-Link Library (DLL) from Visual Studio.
In our badprog_lib.cpp file let’s add the following code:
For MSVC 141 (2017) and Python 3.7
// badprog.com
#include "stdafx.h"
#include <boost/python.hpp>
// ----------------------------------------------------------------------------
// sayHello
// ----------------------------------------------------------------------------
char const* sayHello() {
//
return "Hello world from Badprog :D";
}
// ----------------------------------------------------------------------------
// BOOST_PYTHON_MODULE(badprog_lib)
// It creates the badprog_lib module to import from Python
// ----------------------------------------------------------------------------
BOOST_PYTHON_MODULE(badprog_lib) {
//
boost::python::def("welcome", sayHello);
}
For MSVC 142 (2019) and Python 3.9
// badprog.com
#include "pch.h"
#define BOOST_PYTHON_STATIC_LIB
#include <boost/python.hpp>
// ----------------------------------------------------------------------------
// sayHello
// ----------------------------------------------------------------------------
char const* sayHello() {
//
return "Hello world from Badprog :D";
}
// ----------------------------------------------------------------------------
// BOOST_PYTHON_MODULE(badprog_lib)
// It creates the badprog_lib module to import from Python
// ----------------------------------------------------------------------------
BOOST_PYTHON_MODULE(badprog_lib) {
//
boost::python::def("welcome", sayHello);
}
Then from Visual Studio > Build > Build badprog_lib.
After the build, you should have these lines in your Visual Studio Build Output:
1>------ Build started: Project: badprog_lib, Configuration: Debug x64 ------
1>dllmain.cpp
1> Creating library C:\dev\c++\py\badprog_lib\x64\Debug\badprog_lib.lib and object C:\dev\c++\py\badprog_lib\x64\Debug\badprog_lib.exp
1>badprog_lib.vcxproj -> C:\dev\c++\py\badprog_lib\x64\Debug\badprog_lib.dll
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
If yes you can check that the following DLL has been created:
- C:\dev\c++\py\badprog_lib\x64\Debug\badprog_lib.dll
This DLL will serve as API for our Python script.
Now take this DLL and move it to the following directory:
- C:\dev\c++\py\badprog_lib
So we’ve this file like this:
- C:\dev\c++\py\badprog_libbadprog_lib.dll
Rename the extension from .dll to .pyd.
You have now the following file:
- C:\dev\c++\py\badprog_libbadprog_lib.pyd
This extension does really matter because without it the Python script won’t be able to import it.
We’ve now 2 options in order to get the code from the badprog_lib.pyd library.
- Directly by typing the code from the Python console, line by line
- Creating a Python file and call this file from any console (PowerShell for example)
Typing the code from the Python console
From the C:\dev\c++\py\badprog_lib directory, open a console.
Then type:
$ py
Your console will become a Python interpreter.
And you should see something like this appears:
PS C:\dev\c++\py\badprog_lib> py
Python 3.7.5 (tags/v3.7.5:5c02a39a0b, Oct 15 2019, 00:11:34) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
If yes, good news, you are in the Python console.
Let’s now import our library and type the following command:
import badprog_lib
If nothing has happened, then that’s great.
Let’s continue by calling our C++ code:
badprog_lib.welcome()
The welcoming message should appears:
'Hello world from Badprog :D'
So to sum up here what you should have typed and seen:
PS C:\dev\c++\py\badprog_lib> py
Python 3.7.5 (tags/v3.7.5:5c02a39a0b, Oct 15 2019, 00:11:34) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import badprog_lib
>>> badprog_lib.welcome()
'Hello world from Badprog :D'
>>>
Creating a Python file and call it from a console
Let’s create a file named badprog_script.py in the same directory, so we’ve the following:
- C:\dev\c++\py\badprog_libbadprog_script.py
In this file we have to type the following code, that is exactly the same as the previous command in the Python interpreter:
# badprog.com
import badprog_lib
print(badprog_lib.welcome())
And now from this directory, open any console (Git bash, PowerShell, Cmd, etc.) and type:
$ py badprog_script.py
The output result will be:
Hello world from Badprog :D
Conclusion
A lot of things to check and set.
But you are now able to build a shared library directly from Visual Studio, call the Boost.Python library from a C++ code and use it with Python.
Good job, you did it.