Integrating Python functionality into C++ applications can be a powerful way to leverage the strengths of both languages. A Python virtual environment, often abbreviated as venv
, is a self-contained directory tree that contains installation for a specific version of Python, as well as additional packages. The purpose of creating a virtual environment is to isolate the dependencies of a project, ensuring that it can run independently of the system-wide Python installation and the packages installed there. This tutorial explains how to call Python function from C++ while using virtual environment.
The following code snippet begins by getting the path of the current C++ script and setting up a Python configuration for an isolated environment. The virtual environment's Python executable path (<app_path>/venv/bin/python
) is then determined and configured. After initializing the Python interpreter with the specified settings, the script's directory is added to the Python sys.path
.
The Python module test
(test.py
script) is imported, and the sum
function is retrieved. A Python list with two float values is created, and the Python function is called with this list as an argument. The result is then converted to a double, and the output is displayed.
#include <Python.h>
#include <filesystem>
#include <iostream>
int main(int argc, char *argv[])
{
std::filesystem::path script(argv[0]);
PyConfig config;
PyConfig_InitIsolatedConfig(&config);
auto fullPath = std::filesystem::current_path() / script.parent_path();
auto venv_executable = (fullPath / "venv/bin/python").wstring();
PyConfig_SetString(&config, &config.executable, venv_executable.c_str());
Py_InitializeFromConfig(&config);
PyConfig_Clear(&config);
PyObject * sysPath = PySys_GetObject("path");
PyList_Insert(sysPath, 0, PyUnicode_FromString(script.parent_path().c_str()));
PyObject * pModule = PyImport_ImportModule("test");
PyObject * pFunc = PyObject_GetAttrString(pModule, "sum");
PyObject * list = PyList_New(2);
PyList_SetItem(list, 0, PyFloat_FromDouble(2.0));
PyList_SetItem(list, 1, PyFloat_FromDouble(5.0));
double result = PyFloat_AsDouble(PyObject_CallFunction(pFunc, "O", list));
std::cout << result << std::endl;
Py_Finalize();
return 0;
}
Within the project directory, create a CMakeLists.txt
file:
cmake_minimum_required(VERSION 3.27)
project(myapp)
set(CMAKE_CXX_STANDARD 17)
find_package(Python3 COMPONENTS Development REQUIRED)
add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME} Python3::Python)
In the project directory, run the following CMake command to generate the build scripts and configure the project:
cmake -S . -B build
Execute the given CMake command to build the project:
cmake --build build
Go to build
directory and create Python virtual environment:
cd build && python -m venv venv
Activate virtual environment by using the following command:
venv\Scripts\activate.bat
source venv/bin/activate
When a virtual environment has been activated, install NumPy package:
pip install numpy
Inside the build
directory, create a Python script named test.py
for calculating the sum of the elements in the input array.
import numpy as np
def sum(arr):
return np.sum(arr)
Finally, you can run the program as follows:
./build/myapp
Output:
7
Leave a Comment
Cancel reply