C++;和嵌入的Python-NUL终止字符串 我正在研究将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();

C++;和嵌入的Python-NUL终止字符串 我正在研究将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();,c++,python,string,embedded-language,termination,C++,Python,String,Embedded Language,Termination,pOpts和pInput都是使用代码前面的PyString\u FromString生成的。我遇到的问题是,当我尝试使用PyString_AsString检索输出时,返回值被NUL终止。不幸的是,因为我正在生成PDF文档,NUL不仅是允许的,而且几乎可以保证。谁能告诉我如何将字符串数据从Python返回到C++而不结束它遇到的第一个NUL?< /P> 另外一个问题是,此代码可以作为后台服务的一部分多次调用,后台服务从传入的打印数据创建PDF文档。第一次调用此代码时,它会按预期工作。在Py\u I

pOpts和pInput都是使用代码前面的
PyString\u FromString
生成的。我遇到的问题是,当我尝试使用PyString_AsString检索输出时,返回值被NUL终止。不幸的是,因为我正在生成PDF文档,NUL不仅是允许的,而且几乎可以保证。谁能告诉我如何将字符串数据从Python返回到C++而不结束它遇到的第一个NUL?< /P> 另外一个问题是,此代码可以作为后台服务的一部分多次调用,后台服务从传入的打印数据创建PDF文档。第一次调用此代码时,它会按预期工作。在
Py\u Initialize()
之后,任何后续调用都会在指示行失败。如果您能帮助确定那里发生了什么,我们将不胜感激。提前感谢,有几点:

  • 不要使用字符串。你甚至可能是 能让他们在这里工作吗 扭曲*_StringAndSize() 功能,但它不会是你想要的 希望您应该将数据存储在 一个自定义数据结构(或缓冲区),它只是 字节序列(你真的这么认为吗 希望客户端执行字符串 在Python中对该数据的操作。如果对象确实是缓冲区对象,则应使用

  • 导入的模块的引用计数为2,因为它被保留在中
    sys.modules
    (以便下次尝试导入时提高效率)。永不减损 你不拥有的参考资料,否则你会 使你的程序崩溃。本节 文档应该真正涵盖 这个,但不是

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

  • 您在错误检查方面非常懒惰-大多数Python C/API函数都可以返回NULL以指示抛出了异常,并且您几乎从不检查此值。如果某件事失败了,你会在非常奇怪的地方开始崩溃。您可以在C/API手册的一节中了解这一点

    • 有几点:

      • 不要使用字符串。你甚至可能是 能让他们在这里工作吗 扭曲*_StringAndSize() 功能,但它不会是你想要的 希望您应该将数据存储在 一个自定义数据结构(或缓冲区),它只是 字节序列(你真的这么认为吗 希望客户端执行字符串 在Python中对该数据的操作。如果对象确实是缓冲区对象,则应使用

      • 导入的模块的引用计数为2,因为它被保留在中
        sys.modules
        (以便下次尝试导入时提高效率)。永不减损 你不拥有的参考资料,否则你会 使你的程序崩溃。本节 文档应该真正涵盖 这个,但不是

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

      • 您在错误检查方面非常懒惰-大多数Python C/API函数都可以返回NULL以指示抛出了异常,并且您几乎从不检查此值。如果某件事失败了,你会在非常奇怪的地方开始崩溃。您可以在C/API手册的一节中了解这一点


      NULL!=ASCII NUL。NULL是空指针,NUL是字符串终止符。最好不要两者都混淆@LukeN-已更新,感谢您指出这两个是不同的,但问题仍然是我从Python返回的字符串包含它们,我需要知道如何处理它们。NULL!=ASCII NUL。NULL是空指针,NUL是字符串终止符。最好不要两者都混淆@LukeN-Updated,感谢您指出这两个是不同的,但问题仍然是我从Python返回的字符串中包含了它们,我需要知道如何处理它们。Nick-1。是的,我需要Python中的字符串操作。2.当我注意到额外的引用时,我加入了额外的Py_DECREF,但是代码第二次通过w/或w/o它崩溃了。3 & 4. 我本来不打算将实例化或错误检查保留在当前状态,但在进一步操作之前需要一个概念证明。Nick(也是在1上)正在生成PDF的库希望有一个文件句柄将数据放入其中。我正在使用Python中的StringIO实例远离磁盘,然后在完成PDF生成后,我使用
      outfile.getvalue()
      检索缓冲区内容。到目前为止,我还不能把它转换成ByTeRay-我得到了一个编码错误。你可以在C++中实现一个非常小的对象,它看起来像一个类似于Python的文件对象(只是通过执行适当的协议方法),而不是使用StrugIO实例。这样,你可以将数据保存在内存中,但不必担心空字节或API处理,因为当客户端返回给你时,它已经是一个本地C++数据结构。此外,为了测试的目的,我会使用一个真实的文件,并确保你可以使它工作(并使其健壮)。