0

I'm looking for a way to run C++ code alongside python in real time. I have a neural network program which takes in inputs, and outputs a certain integer. The process of running the neural network is the main "meat" of my program and uses up the most resources so I'd like to code it in c++ to make the overall system more efficient.

What I'm looking to do now if run a python main program that passes in python variables to an external CPP file. The CPP file does its math magic and spits put an integer in Python. Is this possible? Is it advisable?

I have heard of Cython before but would much rather code this by scratch to ensure it is optimized for my specific task.

Kindest reguards!

  • 4
    _"I have heard of Cython before but would much rather code this by scratch to ensure it is optimized for my specific task."_ This is sometimes tempting but usually wrong – Lightness Races in Orbit Jan 10 '20 at 13:09
  • Care to elaborate – user11376058 Jan 10 '20 at 13:13
  • Cython would save the effort of manually writing a C extension, where you would have to deal with python issues like carefully writing reference counting code around every python object. Cython generates C code on compilation as well which you could look at to see how that tool works, along with an annotated .html file which can show the amount of cpython api interaction your code has. – CodeSurgeon Jan 10 '20 at 13:33
  • Try Pyrex. Makes writing C++ extensions for Python easier. – Amit Sharma Jan 10 '20 at 13:56

1 Answers1

0

I did something like you want, but with C++ as start point:

C++ code creates python-like module with C functions. After that C++ code runs target python module, that invokes functions from python-like module. As result, python module is running and is invoking C++ functions.

Here the sample of C++ code:

// Sample of C++ function, which python module invokes
static PyObject* OutDtmf(PyObject* self, PyObject* args)
{
  PyObject* a1;
  if (PyArg_UnpackTuple(args, "OutDtmf", 1, 1, &a1))
  {
    // Check the result
    PyObject* astr = PyUnicode_AsUTF8String(a1);
    const char* ustr = PyBytes_AsString(astr);
    OutDtmf(ustr);
  }

  Py_RETURN_NONE;
}

// Pack of definitions
// --------------------
static PyMethodDef WarSysMethods[] = {
  { "Finish", FinishScript, METH_VARARGS, NULL },
  { "KpsoSetControl", KpsoSetControl, METH_VARARGS, NULL },
  { "KpsoSetLine", KpsoSetLine, METH_VARARGS, NULL },
  { "OutDtmf", OutDtmf, METH_VARARGS, NULL },
  { "PsoSetLine", PsoSetLine, METH_VARARGS, NULL},
  { NULL, NULL, 0 , nullptr }
};


static struct PyModuleDef WarSysModuleDef = {
  PyModuleDef_HEAD_INIT,
  "WarSys",
  NULL,
  -1,
  WarSysMethods };


PyMODINIT_FUNC PyInit_WarSys(void)
{
  PyObject *module;
  module = PyModule_Create(&WarSysModuleDef);
  return module;
}

// Start point for creation of python-like module and loading target python module
void StartScript(bool serverMode, const char* testModuleName)
{
  // Initialization Python -> C++
  PyImport_AppendInittab("WarSys", PyInit_WarSys);

  // Initialization C++ -> Python
  Py_Initialize();

  PyObject* pDict; // borrowed

  TestModule = PyImport_ImportModule(testModuleName);
  if (!TestModule)
  {
    PyErr_Print();
    return;
  }

  pDict = PyModule_GetDict(TestModule);
  // Read function objects
  FuncInit = PyDict_GetItemString(pDict, "Init");
....................


// Invokes python function in module (f.e. Init)
PyObject_CallObject(command.Function, command.Arguments)


in python code use:

import WarSys

and invokes functions WarSys.Finish(False) or other.

Evgeny
  • 1,072
  • 6
  • 6