2012-04-28 2 views
1

Поскольку я понимаю взаимосвязь между C и C++, последнее по существу является продолжением первого и сохраняет определенную степень обратной совместимости. Можно ли предположить, что API-интерфейс python C можно вызвать с помощью кода на C++?Является ли API-интерфейс python полностью совместимым с C++?

Более подробно я отмечаю, что официальная документация на python объединяет расширения C и C++ на одной странице. Нигде я не могу найти C++ API. Это заставляет меня поверить, что один и тот же API безопасен для использования на обоих языках.

Может кто-то подтвердить или опровергнуть это?

EDIT:

Я думаю, что я сделал мой вопрос гораздо сложнее, чем это должно быть. Вопрос в следующем: что я должен сделать, чтобы написать модуль python в C++? Я просто следую тем же направлениям, что указан here, заменяя код C на C++? Есть ли отдельный API?

+0

Вы должны иметь возможность вызывать API Python C с C++, но вы не могли бы написать Python C модуль в C++. –

+0

@DanD. Сейчас я немного смущен, если вы посмотрите на эту страницу, http://docs.python.org/extending/extending.html, он занимается расширением python с помощью C или C++. Мой оригинальный вопрос может быть немного запутанным, поэтому, пожалуйста, позвольте мне перефразировать его. Если я хочу написать модуль python в C++, мне нужно делать что-то по-другому, чем на этой странице (кроме использования C++-конструкций)? Ваш ответ, кажется, предполагает, что это невозможно, отсюда и моя путаница. – blz

+0

@DanD. Позаботьтесь о том, почему?Конечно, любые имена, экспортированные в Python, должны быть в блоке «extern» C «{}» из-за манипуляции с именем (что, конечно, не может экспортировать вещи, которые C не может обрабатывать, например, перегрузки), но я не осознавая любые другие препятствия. – delnan

ответ

4

Я могу подтвердить, что тот же Python C API безопасен для использования на обоих языках, C и C++. Тем не менее, вам сложно предоставить более подробный ответ, если вы не зададите более конкретный вопрос. Есть многочисленные оговорки и проблемы, о которых вы должны знать. Например, ваши расширения Python определяются как C-типы struct, а не как C++, поэтому не ожидайте, что их конструктор/деструктор неявно определены и называется.

Например, беря пример кода из Defining New Types в руководстве Python, он может быть написан на C++ путь, и вы даже можете смешивать-типов C++:

// noddy.cpp 
namespace { 

struct noddy_NoddyObject 
{ 
    PyObject_HEAD 
    // Type-specific fields go here. 
    std::shared_ptr<int> value; // WARNING 
}; 

PyObject* Noddy_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 
{ 
    try { 
     Noddy *self = (Noddy *)type->tp_alloc(type, 0); 
     if (self) { 
      self->value = std::make_shared(7); 
      // or more complex operations that may throw 
      // or extract complex initialisation as Noddy_init function 
      return self; 
     } 
    } 
    catch (...) { 
     // do something, log, etc. 
    } 
    return 0; 
} 

PyTypeObject noddy_NoddyType = 
{ 
    PyObject_HEAD_INIT(NULL) 
    // ... 
} 

} // unnamed namespace 

Но, ни конструктор, ни деструктор std::shared_ptr. Итак, не забудьте определить функцию dealloc для вашего noddy_NoddyType, где вы сбросите value с помощью nullptr. Зачем даже задавать значение shared_ptr, вы можете спросить. Полезно, если вы используете расширение Python в C++ с исключениями, чтобы избежать преобразования типов и приведения, чтобы иметь более плавную интеграцию внутри определений вашей реализации, обработка ошибок на основе исключения может быть проще и т. Д. И, несмотря на тот факт, что ваши объекты noddy_NoddyType управляются машинами, реализованными в чистом C, благодаря функции deallocvalue будет выпущен в соответствии с известными правилами RAII.

Здесь Вы можете найти интересный пример почти бесшовной интеграции Python C API с языка C++: How To catch Python stdout in c++ code

+0

Прежде всего, большое спасибо за ваш тщательный и подробный ответ. Я понятия не имел об этих оговорках! Просто один быстрый вопрос: можно ли избежать некоторых из этих проблем с помощью 'boost.Python'? Мне сказали, что эта библиотека больше ориентирована на разработку на C++, чем на Python.h. – blz

+0

Добро пожаловать. Да, конечно, Boost.Python будет решать почти все такие проблемы для вас. Мой пример основан на простой API Python C, но Boost.Python предоставляет вам абстракцию C++ поверх API Python C, поэтому вы можете забыть о большинстве проблем. – mloskot

+1

Отлично, тогда я начну смотреть на повышение. Еще раз спасибо - полезные ответы, подобные вашим, заставляют меня вернуться к SO! – blz

1

API Python C можно вызывать в коде C++. Расширения Python C++ написаны с использованием того же C API, что и C-расширения, или с использованием некоторых сторонних API, таких как boost::python.

+0

Блестяще, спасибо! Я обязательно отвечу на ваш ответ в ближайшее время. Должен ли я делать что-то по-другому при кодировании на C++? – blz