-
Notifications
You must be signed in to change notification settings - Fork 0
/
c_call_py_main.cpp
109 lines (95 loc) · 4.31 KB
/
c_call_py_main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#ifndef PY_SSIZE_T_CLEAN
#define PY_SSIZE_T_CLEAN
#include <Python.h>
#endif
// #include <boost/python.hpp>
#include <iostream>
#include <numpy/arrayobject.h>
// #include <boost/python/numpy.hpp>
// namespace p = boost::python;
// namespace np = boost::python::numpy;
int main(void) {
// Initialize
std::cout << "Py_IsInitialized() = " << Py_IsInitialized() << "\n";
Py_Initialize();
import_array();
// np::initialize();
std::cout << "Py_IsInitialized() = " << Py_IsInitialized() << "\n";
// Import python functions
PyObject * sys = PyImport_ImportModule("sys");
PyObject * path = PyObject_GetAttrString(sys, "path");
PyList_Append(path, PyUnicode_FromString(".."));
PyObject * moduleString = PyUnicode_FromString((char*) "c_call_py_fun");
PyObject * modul = PyImport_Import(moduleString);
PyObject * dict = PyModule_GetDict(modul);
PyObject * func = PyDict_GetItemString(dict, "pyfun");
// PyObject * output = PyObject_CallObject(func, NULL);
// Construct python function input
npy_intp inputSize[2];
inputSize[0] = 2;
inputSize[1] = 3;
double inputData[] = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0};
PyObject* input = PyArray_SimpleNewFromData(2, inputSize, PyArray_FLOAT64, inputData);
PyObject* pyArgs = PyTuple_New(1);
PyTuple_SetItem(pyArgs, 0, input);
// PyObject* pyValue = PyLong_FromLong(2); // Convert 2 to a Python integer.
// Call python function
PyObject * output = PyObject_CallObject(func, pyArgs);
// Interpret python function output
PyArrayObject * outputArray = reinterpret_cast<PyArrayObject *>(output);
// If there are multiple outputs from the python function, use the following
// int outputVarNum = PyTuple_Size(output);
// std::cout << "outputVarNum = " << outputVarNum << "\n\n";
// PyObject * tupleObj0 = PyTuple_GetItem(output, 0);
// PyArrayObject * outputArray = reinterpret_cast<PyArrayObject *>(tupleObj0);
int outputNDim = PyArray_NDIM(outputArray);
if (outputNDim != 2) {
throw std::runtime_error(
"expecting a 2D array but got " + std::to_string(outputNDim));
}
npy_intp* outputSize = PyArray_DIMS(outputArray);
npy_intp outputRows = outputSize[0], outputCols = outputSize[1];
void* outputPtr = PyArray_DATA(outputArray);
int* intOutputPtr = static_cast<int *>(outputPtr);
std::cout << "outputRows = " << outputRows << "\n";
std::cout << "outputCols = " << outputCols << "\n";
for (int iRow = 0; iRow < outputRows; iRow++) {
for (int iCol = 0; iCol < outputCols; iCol++) {
int temp = intOutputPtr[iRow * outputCols + iCol];
std::cout << temp << "\t";
}
std::cout << "\n";
}
// There are probably still some memory leaks, need to fix
std::cout << "Py_IsInitialized() = " << Py_IsInitialized() << "\n";
std::cout << "sys: " << Py_REFCNT(sys) << "\n";
std::cout << "path: " << Py_REFCNT(path) << "\n";
std::cout << "moduleString: " << Py_REFCNT(moduleString) << "\n";
std::cout << "modul: " << Py_REFCNT(modul) << "\n";
std::cout << "dict: " << Py_REFCNT(dict) << "\n";
std::cout << "func: " << Py_REFCNT(func) << "\n";
std::cout << "input: " << Py_REFCNT(input) << "\n";
std::cout << "pyArgs: " << Py_REFCNT(pyArgs) << "\n";
std::cout << "output: " << Py_REFCNT(output) << "\t" << PyArray_DATA(output) << "\n";
std::cout << "outputArray: " << Py_REFCNT(outputArray) << "\t" << PyArray_DATA(outputArray) << "\n";
std::cout << "\n";
Py_XDECREF(pyArgs);
Py_XDECREF(outputArray);
// Py_XDECREF(func);
Py_XDECREF(modul);
Py_XDECREF(moduleString);
Py_XDECREF(path);
Py_Finalize();
std::cout << "Py_IsInitialized() = " << Py_IsInitialized() << "\n";
std::cout << "sys: " << Py_REFCNT(sys) << "\n";
std::cout << "path: " << Py_REFCNT(path) << "\n";
std::cout << "moduleString: " << Py_REFCNT(moduleString) << "\n";
std::cout << "modul: " << Py_REFCNT(modul) << "\n";
std::cout << "dict: " << Py_REFCNT(dict) << "\n";
std::cout << "func: " << Py_REFCNT(func) << "\n";
std::cout << "input: " << Py_REFCNT(input) << "\n";
std::cout << "pyArgs: " << Py_REFCNT(pyArgs) << "\n";
std::cout << "output: " << Py_REFCNT(output) << "\n";
std::cout << "outputArray: " << Py_REFCNT(outputArray) << "\n";
std::cout << "\n";
}