无法从嵌入的Python返回长整型到C++

3 投票
1 回答
502 浏览
提问于 2025-04-18 11:35

你好,我正在尝试从嵌入的Python代码返回一个值(119599936)到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();

我试过了。

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

以上的方法都没有成功,当我尝试返回数字119599936时,出现的错误是:

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

1 个回答

1

你的代码没有进行任何错误检查,而且你也没有提供memory_leak_test模块的源代码,所以我们很难猜测问题出在哪里。我猜可能是memory_leak_test没有成功导入,或者memory_leak_test.begin("CacheSetup")抛出了异常,或者返回了None,而不是你代码所期待的数字。

为了调试这个问题,可以按照以下建议来重写代码:

  • 检查可能返回错误的Python/C函数的错误信息。每当出现你无法处理的错误时,调用 PyErr_Print() 并终止当前执行(除非你预期会出现这个错误并想要妥善处理,那样的话就调用 PyErr_Clear())。

  • 当你不再需要某些对象时,使用 Py_DECREF 来减少它们的引用计数。这些对象通常是像 PyString_FromStringPyTuple_PackPyObject_CallOject 这样的返回值。

  • 学习并使用一些方便的函数,比如 PyObject_CallFunctionPyObject_CallMethodPyImport_ImportModule,这些函数可以大大减少创建临时字符串和元组的重复代码。找到这些函数的最好方法是查看现有的Python/C源代码,比如Python自带的那些。

  • 使用 PyObject_Print() 来打印中间结果,以便调试。

根据以上建议,这里是你代码的一个可能修改版本:

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();

撰写回答