1

我正在将 Python 2.6 嵌入到现有的 c++ 应用程序中。到目前为止,我已经链接了库,并且能够成功初始化 Python 解释器,还可以将数据传输到 Python。我在检索它时遇到了麻烦,希望有人能引导我正确的方向。我正在处理这个:

Py_Initialize();

pModule = PyImport_ImportModule("cBuffers"); // This crashes after 1st call.
pDict = PyModule_GetDict(pModule);
pClass = PyDict_GetItemString(pDict, "rf_pdf");
pMeth = PyString_FromString("main");

if (PyCallable_Check(pClass) && PyClass_Check(pClass)) {
  pInstance = PyInstance_New(pClass, NULL, NULL);
  pOutput = PyObject_CallMethodObjArgs(pInstance, pMeth, pOpts, pInput, NULL);
}

if (pOutput != NULL) {
  string pPdf = PyString_AsString(pOutput);
  Py_DECREF(pOutput);
} else {
  PyErr_Print();
}

// Cleanup
Py_DECREF(pModule);
Py_DECREF(pModule); // Has an extra reference, not positive why.
Py_DECREF(pMeth);
Py_DECREF(pInstance);
Py_DECREF(pOpts);
Py_DECREF(pInput);

Py_Finalize();

pOpts 和 pInput 都是使用PyString_FromString前面的代码生成的。我遇到的问题是,当我尝试使用 PyString_AsString 检索输出时,返回值为 NUL 终止。不幸的是,因为我正在生成 PDF 文档,所以 NUL 不仅是允许的,而且几乎可以保证。谁能告诉我如何将字符串数据从 Python 返回到 C++ 而不会在它遇到的第一个 NUL 处结束?

作为一个附加问题,此代码可以作为后台服务的一部分被多次调用,该后台服务从传入的打印数据创建 PDF 文档。第一次调用此代码时,它按预期工作。任何后续调用都在 . 之后的指示行失败Py_Initialize()。关于如何确定那里发生了什么的帮助也将不胜感激。提前致谢,

4

1 回答 1

1

几点:

  • 不要使用字符串。您甚至可以通过对 *_StringAndSize() 函数的一些扭曲使它们在这里工作,但这不是您想要的。您应该将数据存储在只是一个字节序列的自定义数据结构(或缓冲区)中(您真的希望客户端在 Python 中对此数据执行字符串操作吗?)。如果你的对象真的是一个缓冲区对象,你应该使用Buffer API

  • 您导入的模块的引用计数为 2,因为它被保留 sys.modules(为了下次尝试导入它时的效率)。 永远不要对不属于你的引用进行 decref 引用,否则你会崩溃你的程序。文档的Importing Modules部分应该真正涵盖这一点,但它没有。

  • 每次执行这些操作时初始化 Python 并将其拆除是非常昂贵的。您应该尝试重新组织您的用例,以便您Py_Initialize只能在应用程序启动时(或第一次需要 Python)调用一次,然后仅Py_Finalize在您的应用程序确实使用 Python 完成或退出时调用。

  • 您对错误检查非常懒惰 - 大多数 Python C/API 函数都可以返回 NULL 以指示已引发异常,而您几乎从不检查此值。如果某些事情失败了,您将开始在非常奇怪的地方崩溃。您可以在 C/API 手册的异常处理部分阅读相关内容。

于 2010-10-08T18:03:45.920 回答