[C / C ++] Pass the value calculated in C / C ++ to a python function to execute the process, and use that value in C / C ++.

Summary of this article

--Pass the value calculated in the C / C ++ source to the python function, and receive the execution result in the C / C ++ source.

What to do in this article

--Create an appropriate value in C / C ++ --Print the value with a python function --python functions also return appropriate values --Print the value returned by the python function on the C / C ++ side as well.

(The values of variables used in the program have no meaning)

Source code

C/C++

main.cpp


#include <iostream>
#include <vector>
#include <Python.h>

bool isCallable(const char *functionName, PyObject *pythonFunc) {
    if (pythonFunc && PyCallable_Check(pythonFunc)) {
        return true;
    } else {
        std::cerr << "Failed to load the function [" << functionName << "]." << std::endl;
        return false;
    }
}

int main(int argc, char *argv[]) {
    const char *pythonFileName = "script"; // The extension (.py) must be removed.
    const char *functionName = "test_func"; // This function must be included in the script.

    Py_Initialize();
    PyObject *sys = PyImport_ImportModule("sys");
    PyObject *path = PyObject_GetAttrString(sys, "path");
    PyList_Append(path, PyString_FromString(".")); // Add the current directory to the python path list since the script file is in there.
    PyRun_SimpleString("import os, sys\n");

    // load the function from the script
    PyObject *pythonName = PyString_FromString(pythonFileName);
    PyObject *pythonModule = PyImport_Import(pythonName);
    Py_DECREF(pythonName);
    PyObject *pythonFunc = PyObject_GetAttrString(pythonModule, functionName);
    if (!isCallable(functionName, pythonFunc))
        exit(-1);


    // Create data which will be passed to the python's function.
    // Because the numbers of the argument is 2, the python's function must receive 2 arguments (see the script file).
    int pythonFuncArgNum = 2;
    PyObject *pythonArgs = PyTuple_New(pythonFuncArgNum);


    // Create the first argument.
    int dataNum = 3;
    int channelNum = 2;
    int measurementNum = 4;
    PyObject *params = PyList_New(3);
    PyList_SET_ITEM(params, 0, PyInt_FromLong(dataNum));
    PyList_SET_ITEM(params, 1, PyInt_FromLong(channelNum));
    PyList_SET_ITEM(params, 2, PyInt_FromLong(measurementNum));
    PyTuple_SetItem(pythonArgs, 0, params); // Set the first argument.


    // Create the second argument.
    PyObject *datas = PyTuple_New(dataNum);
    for (int i = 0; i < dataNum; i++) {
        PyObject *data = PyTuple_New(channelNum);
        PyObject *channel0 = PyList_New(measurementNum);
        PyObject *channel1 = PyList_New(measurementNum);
        for (int j = 0; j < measurementNum; j++) {
            PyList_SET_ITEM(channel0, j, PyFloat_FromDouble(i + j * 2.0));
            PyList_SET_ITEM(channel1, j, PyFloat_FromDouble(i * 2.0 + j * 2.0));
        }
        PyTuple_SetItem(data, 0, channel0);
        PyTuple_SetItem(data, 1, channel1);
        PyTuple_SetItem(datas, i, data);
    }
    PyTuple_SetItem(pythonArgs, 1, datas); // Set the second argument.


    // Call the python's function and print the returned values.
    PyObject *pythonValue = PyObject_CallObject(pythonFunc, pythonArgs);
    Py_DECREF(pythonArgs);
    std::cout << "Print the results returned from the python function in the C++ source code." << std::endl;
    for (int i = 0; i < (int)PyList_Size(pythonValue); i++)
        std::cout << i << " , " << PyFloat_AsDouble(PyList_GetItem(pythonValue, i)) << std::endl;


    return 0;
}

python

script.py


#! /usr/bin/env python
# -*- coding: utf-8 -*-

import sys
import numpy as np

print 'Scripts written in outside of python functions will be called when this script is loaded by the C++ source code.\n'


# The function must have 2 arguments because the C++ source code gives the function 2 arguments.
def test_func(params, datas):
    print 'Start the python function.'

    # Copy the parameters.
    data_num = params[0]
    channel_num = params[1]
    measurement_num = params[2]
    print 'data_num =', data_num, ', channel_num =', channel_num, ', measurement_num =', measurement_num

    # Print the second arguments
    for i in range(data_num):
        for j in range(measurement_num):
            print 'i =', i, ', channel0 =', datas[i][0][j], ', channel1 =', datas[i][1][j]

    # Create a dummy result and return it.
    values = []
    for i in range(data_num):
        values.append(i * 3.0)

    print 'The python function will return an array (vector) data.\n'

    return values

compile

g++ main.cpp -o call_py_func_from_c -L/usr/lib/python2.7 -lpython2.7 -I/usr/include/python2.7

Please change the python version and path accordingly.

Execution result

Place the C / C ++ and python files in the same directory and run them there (because script.py cannot be found unless the python path is set). In the C / C ++ source code, there is a process to set the current directory to the python path.

Scripts written in outside of python functions will be called when this script is loaded by the C++ source code.

Start the python function.
data_num = 3 , channel_num = 2 , measurement_num = 4
i = 0 , channel0 = 0.0 , channel1 = 0.0
i = 0 , channel0 = 2.0 , channel1 = 2.0
i = 0 , channel0 = 4.0 , channel1 = 4.0
i = 0 , channel0 = 6.0 , channel1 = 6.0
i = 1 , channel0 = 1.0 , channel1 = 2.0
i = 1 , channel0 = 3.0 , channel1 = 4.0
i = 1 , channel0 = 5.0 , channel1 = 6.0
i = 1 , channel0 = 7.0 , channel1 = 8.0
i = 2 , channel0 = 2.0 , channel1 = 4.0
i = 2 , channel0 = 4.0 , channel1 = 6.0
i = 2 , channel0 = 6.0 , channel1 = 8.0
i = 2 , channel0 = 8.0 , channel1 = 10.0
The python function will return an array (vector) data.

Print the results returned from the python function in the C++ source code.
0 , 0
1 , 3
2 , 6

Summary

I passed the value calculated in C / C ++ to the python function, and made a program to return the processing performed in the python function to C / C ++.

He says, "I know there are good libraries (deep learning, etc.) in python, but I don't like writing all programs in python" (I can't keep up with new ones ...). So, I basically wrote it in C / C ++ and thought it would be nice to be able to call the python library only when needed.

I think there are already similar pages, but to make sure I don't forget ...

Recommended Posts

[C / C ++] Pass the value calculated in C / C ++ to a python function to execute the process, and use that value in C / C ++.
How to use the C library in Python
To execute a Python enumerate function in JavaScript
Use libsixel to output Sixel in Python and output a Matplotlib graph to the terminal.
[Mac] A super-easy way to execute system commands in Python and output the results
How to use the __call__ method in a Python class
How to get the last (last) value in a list in Python
I also tried to imitate the function monad and State monad with a generator in Python
[Introduction to Python] How to use the in operator in a for statement?
A function that measures the processing time of a method in python
How to use is and == in Python
Write a script in Shell and Python to notify you in Slack when the process is finished
[Python] The role of the asterisk in front of the variable. Divide the input value and assign it to a variable
How to divide and process a data frame using the groupby function
[Python] Explains how to use the range function with a concrete example
Connect to postgreSQL from Python and use stored procedures in a loop.
[Python] How to use the enumerate function (extract the index number and element)
The eval () function that calculates a string as an expression in python
I want to pass an argument to a python function and execute it from PHP on a web server
How to generate permutations in Python and C ++
Get the caller of a function in Python
[Python] How to use hash function and tuple.
Function to extract the maximum and minimum values ​​in a slice with Go
A solution to the problem that the Python version in Conda cannot be changed
[Python] Smasher tried to make the video loading process a function using a generator
I want to get the file name, line number, and function name in Python 3.4
[Python] A function that aligns the width by inserting a space in text that has both full-width and half-width characters.
How to retrieve the nth largest value in Python
Try to make a Python module in C language
Specifies the function to execute when the python program ends
Execute Python function from Powershell (how to pass arguments)
How to use the model learned in Lobe in Python
I felt that I ported the Python code to C ++ 98.
How to execute a command using subprocess in Python
[Python] How to call a c function from python (ctypes)
I want to use the R dataset in python
What does the last () in a function mean in Python?
A Python script that crawls RSS in Azure Status and posts it to Hipchat
How to execute a schedule by specifying the Python time zone and execution frequency
How to store Python function in Value of dictionary (dict) and call function according to Key
How to unit test a function containing the current time using freezegun in python
Notes on how to use StatsModels that can use linear regression and GLM in python
In Python3.8 and later, the inverse mod can be calculated with the built-in function pow.
A note that runs an external program in Python and parses the resulting line
A solution to the problem that files containing [and] are not listed in glob.glob ()
It is easy to execute SQL with Python and output the result in Excel
How to find the first element that matches your criteria in a Python list
I wanted to create a dll to use a function written in C from Python with ctypes, but I had a hard time
The return value (generator) of a function that combines finally and yield must not be passed directly to next
Jedi-vim shortcut command that allows you to refer to the definition source and definition destination in Python
Create a function in Python
Output "Draw ferns programmatically" to the drawing process in Python
A function that divides iterable into N pieces in Python
How to start a simple WEB server that can execute cgi of php and python
Use callback function in Python
"Cython" tutorial to make Python explosive: Pass a C ++ class object to a class object on the Python side. Part ①
[Small story] A painstaking measure when you have to execute a function before import in Python
Check the argument type annotation when executing a function in Python and make an error
Change the standard output destination to a file in Python
Get the value of a specific key up to the specified index in the dictionary list in Python
A story that makes it easy to estimate the living area using Elasticsearch and Python