我正在努力将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 Terminated。不幸的是,因为我正在生成PDF文档,不仅允许NUL,它们几乎得到保证。任何人都可以告诉我如何将Python中的字符串数据返回到C ++而不会在它遇到的第一个NUL结束?
作为附加问题,此代码可作为后台服务的一部分多次调用,后台服务从传入的打印数据创建PDF文档。第一次调用此代码时,它按预期工作。任何后续调用都在Py_Initialize()
之后的指示行失败。有关如何确定正在发生的事情的帮助也将受到最多的赞赏。提前谢谢,
答案 0 :(得分:1)
几点:
不要使用字符串。你甚至可能是 能够让他们与一些人一起工作 扭曲* _StringAndSize() 功能,但它不会是你 想。您应该存储您的数据 一个自定义数据结构(或缓冲区) 一个字节序列(你真的 希望客户执行字符串 在Python中对这些数据进行操作?)。如果您的对象确实是缓冲区对象,则应使用Buffer API。
您导入的模块的引用数为2,因为它被保留
sys.modules
(为了您下次尝试导入时的效率)。 从不减少
您不拥有的参考文献或您将拥有的参考文献
崩溃你的程序。 Importing
Modules部分
文档应该真正涵盖
这个,但事实并非如此。
初始化Python并在每次执行这些操作时将其拆除都非常昂贵。您应该尝试重新组织您的用例,以便在应用程序启动时(或第一次需要Python时)只调用Py_Initialize
一次,然后在应用程序时仅调用Py_Finalize
肯定用Python完成,或者当它退出时。
你对错误检查非常懒惰 - 大多数Python C / API函数都可以返回NULL来表示抛出了异常,而且你几乎从不检查这个值。如果出现问题,你会在非常奇怪的地方开始崩溃。您可以在C / API手册的Exception Handling部分阅读相关内容。