1

I'm writing a C++ program that requires Python (3.11) code to be embedded into it and am using Python.h to try and accomplish this. The general idea is that my a python script, which will be stored by the C++ program as a string, as I'll be performing operations on the source at runtime, will contain a "main()" function which returns an array of known size.

I'm aware I can do it via:

...
PyObject *pName = PyString_FromString("main");
PyObject *pModule = PyImport_Import(pName)
...

However, in order to actually execute the script, I would need to write it to a file just so that python could read it again. This adds extra time to execution that I'd prefer to avoid. Isn't there some way in which I can pass python the source code directly as a string and work from there? Or am I just screwed?

EDIT: BTW, PyRun_SimpleString does not do what I want, as it doesn't return anything from the executed code.

  • "However, in order to actually execute the script, I would need to write it to a file just so that python could read it again" and whats wrong with that? – 463035818_is_not_an_ai Nov 28 '22 at 11:58
  • Added "This adds extra time to execution that I'd prefer to avoid" for extra clarity – Krohnus Melavea Nov 28 '22 at 12:01
  • Fair enough. Next try: PyRun_String() ? https://docs.python.org/3/c-api/veryhigh.html#c.PyRun_String Example Usage here: https://schneide.blog/2011/10/10/embedding-python-into-cpp/ – nick Nov 28 '22 at 12:19

1 Answers1

2

Found the answer thanks to nick in the comments. An example of usage of PyRun_String: https://schneide.blog/2011/10/10/embedding-python-into-cpp/, and extracting list variables from python script https://docs.python.org/3/c-api/list.html The final frankenstein:

PyObject *main = PyImport_AddModule("__main__");
PyObject *globalDictionary = PyModule_GetDict(main);
PyObject *localDictionary = PyDict_New();
PyRun_String("a=[0, 1, 2, 3, 4, 5]", Py_file_input, globalDictionary, localDictionary);
    
PyObject *result = PyDict_GetItemString(localDictionary, "a");

double a[6];
for (int i = 0; i < PyList_Size(result); i++) {
    a[i] = PyFloat_AsDouble(PyList_GetItem(result, i));
}