3

Hi I am trying to return a value (119599936) from the embedded python to C++

Py_Initialize();
PyObject* myModuleString = PyString_FromString((char*)"memory_leak_test");
PyObject* myModule = PyImport_Import(myModuleString);
PyObject* myFunction = PyObject_GetAttrString(myModule,(char*)"begin");
PyObject* args = PyTuple_Pack(1,PyString_FromString("CacheSetup"));
PyObject* myResult = PyObject_CallObject(myFunction, args);
double result = PyFloat_AsDouble(myResult);// <<<<<<<<< I guess thts where i'm goin wrong
std::cout << result << std::endl;
Py_Finalize();

I tried

unsigned long result = PyLong_AsUnsignedLong(myResult);
unsigned long long result = PyLong_AsUnsignedLongLongMask(myResult);
double result = PyLong_AsDouble(myResult2);

None of the above seemed to work for the when I try to return the number 119599936, the error i'm getting is

Exception SystemError: '..\\Objects\\longobject.c:739: bad argument to internal
function' in 'garbage collection' ignored
Fatal Python error: unexpected exception during garbage collection

1 Answer 1

1

Since your code performs no error checking whatsoever, and you don't provide the source to the memory_leak_test module, it's anyone's guess what went wrong. My guess would be that memory_leak_test failed to import, or that memory_leak_test.begin("CacheSetup") raised an exception or returned None instead of returning a number like your code expects.

To debug this problem, rewrite with the following guidelines in mind:

  • Check errors from Python/C functions that may return them. Whenever an error you can't handle appears, call PyErr_Print() and terminate current execution (unless you are expecting the error and want to handle it properly - in that case, call PyErr_Clear() instead.)

  • Invoke Py_DECREF on objects returned as new references once you no longer need them. Examples of these are the return values of PyString_FromString, PyTuple_Pack, and PyObject_CallOject.

  • Learn of and use convenience functions such as PyObject_CallFunction, PyObject_CallMethod, and PyImport_ImportModule which significantly reduce boilerplate code for creating temporary strings and tuples. The best way to find these is by perusing existing Python/C sources, such as those that come with Python.

  • Use PyObject_Print() to print intermediate results for debugging.

Here is a possible modification of your code according to the above:

Py_Initialize();

PyObject *module = PyImport_ImportModule("memory_leak_test");
if (!module) {
  PyErr_Print();
  return;
}
PyObject *result = PyObject_CallMethod(module, "begin", "s", "CacheSetup");
Py_DECREF(module);
if (!result) {
  PyErr_Print();
  return;
}
printf("got result of type %s\n", Py_TYPE(result)->tp_name);
PyObject_Print(result, stdout, 0);
putchar('\n');

Py_DECREF(result);
Py_Finalize();
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.