C ++ и Embedded Python - завершенные строки NUL - PullRequest
1 голос
/ 08 октября 2010

Я работаю над внедрением 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 Termination.К сожалению, поскольку я создаю PDF-документы, NUL не только разрешены, но и почти гарантированы.Может кто-нибудь сказать мне, как я возвращаю String Data из Python обратно в C ++, не заканчиваясь на первом NUL, с которым он сталкивается?

В качестве дополнительного вопроса, этот код может вызываться несколько раз как часть фоновой службы, которая создаетPDF документы из входящих данных печати.Первый раз, когда этот код вызывается, он работает как положено.Любые последующие вызовы не будут выполняться по указанной линии сразу после Py_Initialize().Помощь в том, как определить, что там происходит, также будет очень полезна.Заранее спасибо,

1 Ответ

1 голос
/ 08 октября 2010

Несколько баллов:

  • Не используйте строки. Вы могли бы даже быть в состоянии заставить их работать здесь с некоторыми искажения * _StringAndSize () функции, но это будет не то, что вы хочу. Вы должны хранить свои данные в пользовательская структура данных (или буфер), которая просто последовательность байтов (вы действительно хотите, чтобы клиенты выполняли строку операции над этими данными в Python?). Если ваш объект действительно является буферным объектом, вы должны использовать Buffer API .

  • Ваш импортированный модуль имеет счет 2, потому что он находится в sys.modules (для эффективности при следующей попытке его импортировать). Никогда decf ссылки у вас нет или вы будете сбой вашей программы. Импорт Модули раздел документация должна действительно охватывать это, но это не так.

  • Довольно дорого инициализировать Python и разбирать его каждый раз, когда вы выполняете эти операции. Вам следует попытаться реорганизовать свой вариант использования так, чтобы вы могли вызывать Py_Initialize только один раз при запуске приложения (или при первом запуске Python), а затем вызывать Py_Finalize только тогда, когда ваше приложение определенно сделано с Python, или когда он выходит.

  • Вы очень ленивы с проверкой ошибок - большинство функций Python C / API могут возвращать NULL, чтобы указать, что было сгенерировано исключение, и вы почти никогда не проверяете это значение. Если что-то не получится, вы начнете падать в очень странных местах. Вы можете прочитать об этом в разделе Обработка исключений руководства C / API.

...