--Erstellen Sie einen geeigneten Wert in C / C ++ --Drucken Sie den Wert mit einer Python-Funktion --python-Funktionen geben auch entsprechende Werte zurück --Drucken Sie den von der Python-Funktion zurückgegebenen Wert auch auf der C / C ++ - Seite.
(Die Werte der im Programm verwendeten Variablen haben keine Bedeutung)
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
Bitte ändern Sie die Python-Version und den Pfad entsprechend.
Platzieren Sie die C / C ++ - und Python-Dateien im selben Verzeichnis und führen Sie sie dort aus (da script.py nur gefunden werden kann, wenn der Python-Pfad festgelegt ist). Im C / C ++ - Quellcode gibt es einen Prozess, um das aktuelle Verzeichnis auf den Python-Pfad festzulegen.
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
Ich habe den in C / C ++ berechneten Wert an die Python-Funktion übergeben und ein Programm erstellt, um die in der Python-Funktion durchgeführte Verarbeitung an C / C ++ zurückzugeben.
Er sagt: "Ich weiß, dass es in Python gute Bibliotheken (Deep Learning usw.) gibt, aber ich schreibe nicht gerne alle Programme in Python" (ich kann nicht mit neuen mithalten ...). Also habe ich es im Grunde genommen in C / C ++ geschrieben und dachte, es wäre schön, die Python-Bibliothek nur bei Bedarf aufrufen zu können.
Ich denke, es gibt bereits ähnliche Seiten, aber um sicherzugehen, dass ich nicht vergesse ...