--Passez la valeur calculée dans la source C / C ++ à la fonction python et recevez le résultat de l'exécution dans la source C / C ++.
--Créez une valeur appropriée en C / C ++ --Imprimer la valeur avec une fonction python
(Les valeurs des variables utilisées dans le programme n'ont aucune signification)
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
g++ main.cpp -o call_py_func_from_c -L/usr/lib/python2.7 -lpython2.7 -I/usr/include/python2.7
Veuillez modifier la version et le chemin de Python en conséquence.
Placez les fichiers C / C ++ et python dans le même répertoire et exécutez-les là-bas (car script.py ne peut être trouvé que si le chemin python est défini). Dans le code source C / C ++, il existe un processus pour définir le répertoire actuel sur le chemin python.
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
J'ai passé la valeur calculée en C / C ++ à la fonction python et j'ai créé un programme pour renvoyer le traitement effectué dans la fonction python vers C / C ++.
Il dit: "Je sais qu'il existe de bonnes bibliothèques (deep learning, etc.) en python, mais je n'aime pas écrire tous les programmes en python" (je ne peux pas suivre les nouveaux ...). Donc, je l'ai essentiellement écrit en C / C ++ et j'ai pensé que ce serait bien de pouvoir appeler la bibliothèque python uniquement lorsque cela est nécessaire.
Je pense qu'il y a déjà des pages similaires, mais pour être sûr de ne pas oublier ...