Embedding Python does not throw an error, but the program crashes anyways
-
wrote on 1 Sept 2021, 15:51 last edited by lfreeman6490 9 Jan 2021, 16:35
I am trying to embed a python interpreter into my c++ gui. I am including Python.h and then in my function
void pl::on_pb_connect_disconnect_clicked() { PyObject* pName, *pModule, *pDict, *pFunc; Py_Initialize(); std::string filename = "test_python_file.py"; const char* cstr1 = filename.c_str(); pName = PyUnicode_FromString(cstr1); pModule = PyImport_Import(pName); pDict = PyModule_GetDict(pModule); std::string function_name = "test_function"; const char* cstr = function_name.c_str(); pFunc = PyDict_GetItemString(pDict, cstr); if (PyCallable_Check(pFunc)) { PyObject_CallObject(pFunc, NULL); } else { PyErr_Print(); } Py_Finalize(); }
The basic idea is that once the 'connect' button is hit, it calls test_function in test_python_file.py. It builds and runs successfully, once it is launched and I hit the 'connect' button, the program crashes. I have cleaned, rebuild, ran qmake, etc. Running in debug mode gives me a division by 0 error. If I comment out the code line by line I see that the errors comes from
pDict = PyModule_GetDict(pModule);
Once that line is used again, the program crashes.
-
Hi,
Since you are using a relative path, is your Python file in the same folder as the executable ?
You should check whether your objects are null just in case something goes wrong. -
Hi,
Since you are using a relative path, is your Python file in the same folder as the executable ?
You should check whether your objects are null just in case something goes wrong.wrote on 1 Sept 2021, 23:06 last edited by@SGaist Hi, Thanks for the response. The python files are in the same folder as my executable. How would I check for null objects? Am I not doing that already? I thought that
if (PyCallable_Check(pFunc)) { PyObject_CallObject(pFunc, NULL); } else { PyErr_Print(); }
Would print out the error message that is returned, is that not correct?
-
@SGaist Hi, Thanks for the response. The python files are in the same folder as my executable. How would I check for null objects? Am I not doing that already? I thought that
if (PyCallable_Check(pFunc)) { PyObject_CallObject(pFunc, NULL); } else { PyErr_Print(); }
Would print out the error message that is returned, is that not correct?
wrote on 1 Sept 2021, 23:11 last edited by@lfreeman6490 Have you verified that the pointers are not null?
-
@lfreeman6490 Have you verified that the pointers are not null?
wrote on 1 Sept 2021, 23:14 last edited by@eyllanesc How would I check for that? Is my if loop at the end of my code not checking for error messages?
-
@eyllanesc How would I check for that? Is my if loop at the end of my code not checking for error messages?
wrote on 1 Sept 2021, 23:16 last edited by eyllanesc 9 Jan 2021, 23:16@lfreeman6490 PyErr_Print only returns python errors, it does not check memory.
what is the output of:
qDebug() << pName << pModule << pDict;
before
PyDict_GetItemString(...)
? -
@lfreeman6490 PyErr_Print only returns python errors, it does not check memory.
what is the output of:
qDebug() << pName << pModule << pDict;
before
PyDict_GetItemString(...)
?wrote on 1 Sept 2021, 23:21 last edited by@eyllanesc There is no difference in the output when entering that line. I cleaned, reran qmake, rebuilt, then ran directly from the executable as well as from qtcreator. The output just says
The program has finished unexpectedly
-
@eyllanesc There is no difference in the output when entering that line. I cleaned, reran qmake, rebuilt, then ran directly from the executable as well as from qtcreator. The output just says
The program has finished unexpectedly
wrote on 1 Sept 2021, 23:23 last edited by@lfreeman6490 I never said that was the solution, do not rush. I'm just asking for some debugging information to analyze the cause of the error.
-
@lfreeman6490 I never said that was the solution, do not rush. I'm just asking for some debugging information to analyze the cause of the error.
wrote on 1 Sept 2021, 23:27 last edited by@eyllanesc Okay, thanks. I just wanted to clearly show what the error message was and what I had done already
-
@eyllanesc Okay, thanks. I just wanted to clearly show what the error message was and what I had done already
wrote on 1 Sept 2021, 23:29 last edited by@lfreeman6490 Comment on the line that generates the error and tell me what is printed on the console
-
@lfreeman6490 Comment on the line that generates the error and tell me what is printed on the console
wrote on 2 Sept 2021, 00:58 last edited by@eyllanesc Okay, commenting out that line gives me hex code errors
0x67b0128 0x0 0x57290610
-
@eyllanesc Okay, commenting out that line gives me hex code errors
0x67b0128 0x0 0x57290610
wrote on 2 Sept 2021, 01:06 last edited by eyllanesc 9 Feb 2021, 01:11@lfreeman6490 From the print we can see that
pModule
is null, so you get this behavior.Change to:
if(!(pModule = PyImport_Import(pName))){ PyErr_Print(); return; }
-
@lfreeman6490 From the print we can see that
pModule
is null, so you get this behavior.Change to:
if(!(pModule = PyImport_Import(pName))){ PyErr_Print(); return; }
wrote on 2 Sept 2021, 01:50 last edited by lfreeman6490 9 Feb 2021, 01:51@eyllanesc Where in the code should I add that? Should that be directly after creating pModule? Or at the very last spot in the code?
-
@eyllanesc Where in the code should I add that? Should that be directly after creating pModule? Or at the very last spot in the code?
wrote on 2 Sept 2021, 02:22 last edited by@lfreeman6490 Change
pModule = PyImport_Import(pName);
-
@lfreeman6490 Change
pModule = PyImport_Import(pName);
wrote on 2 Sept 2021, 02:50 last edited by@eyllanesc Okay so by changing that it is no longer crashing, but it is not calling my function. The function is a simple test function that should return a number
def test_function(): return 7
-
@eyllanesc Okay so by changing that it is no longer crashing, but it is not calling my function. The function is a simple test function that should return a number
def test_function(): return 7
wrote on 2 Sept 2021, 02:56 last edited by@lfreeman6490 It seems that you have not understood the problem. Your code has not imported the module so pModule is null.
-
I am trying to embed a python interpreter into my c++ gui. I am including Python.h and then in my function
void pl::on_pb_connect_disconnect_clicked() { PyObject* pName, *pModule, *pDict, *pFunc; Py_Initialize(); std::string filename = "test_python_file.py"; const char* cstr1 = filename.c_str(); pName = PyUnicode_FromString(cstr1); pModule = PyImport_Import(pName); pDict = PyModule_GetDict(pModule); std::string function_name = "test_function"; const char* cstr = function_name.c_str(); pFunc = PyDict_GetItemString(pDict, cstr); if (PyCallable_Check(pFunc)) { PyObject_CallObject(pFunc, NULL); } else { PyErr_Print(); } Py_Finalize(); }
The basic idea is that once the 'connect' button is hit, it calls test_function in test_python_file.py. It builds and runs successfully, once it is launched and I hit the 'connect' button, the program crashes. I have cleaned, rebuild, ran qmake, etc. Running in debug mode gives me a division by 0 error. If I comment out the code line by line I see that the errors comes from
pDict = PyModule_GetDict(pModule);
Once that line is used again, the program crashes.
wrote on 2 Sept 2021, 06:50 last edited by@lfreeman6490 said in Embedding Python does not throw an error, but the program crashes anyways:
std::string filename = "test_python_file.py"; const char* cstr1 = filename.c_str(); pName = PyUnicode_FromString(cstr1); if(!(pModule = PyImport_Import(pName))){ PyErr_Print(); return; }
From the
0x0
output you really should be able to understand thatPyImport_Import(pName)
returnednullptr
. That means yourtest_python_file.py
could not be loaded, Either the file could not be found, or there is some problem loading it. Hopefully thePyErr_Print();
gave some clue as to why, but you never said anything about what it output.Start by changing your
test_python_file.py
to the full path to where that file is.
1/17