Расширение C ++ до Python с помощью Pybind11

У меня есть код, написанный на c ++, который я пытаюсь использовать в python, не переписывая снова весь код на python, и я использую Pybind11 для создания модуля python для этого. Я пытаюсь добиться этого в Microsoft Visual Studio 2015, следуя этому руководству здесь https://pybind11.readthedocs.io/en/stable/basics.html

В визуальной студии я делал следующие вещи. 1) Загрузил Pybind11 с https://codeload.github.com/pybind/pybind11/zip/master

2) Разархивировал файл

3) В Visual Studio запущен новый пустой проект на C ++.

4) Добавлена ​​папка включения моего интерпретатора Python (C: / python27 / include) и Pybind11 (C: / Pybind11 / include) в каталоги VC ++> каталоги включения

5) Добавлены дополнительные зависимости (C: \ Python27 \ libs \ python27.lib) в Linker> input> Additional dependencies

6) Чтобы использовать выходной файл в Python, мне нужен файл .pyd, поэтому я изменил здесь Свойства конфигурации> Общие> Целевое расширение: .pyd

7) Измените настройки проекта по умолчанию> тип конфигурации на динамическую библиотеку (.dll)

Итак, я могу создать свой проект и сгенерировать файл .pyd, но при импорте этого модуля я получаю следующую ошибку: ImportError: динамический модуль не определяет функцию инициализации (initProject11)

Я искал эту ошибку и получил эту ссылку http://pybind11.readthedocs.io/en/stable/faq.html, но я не смог найти свое решение.

Итак, я ищу решение вышеуказанной проблемы. Заранее большое спасибо.

вот мой код файла CPP

#include <pybind11/pybind11.h>

int add(int i, int j) {
return i + j;
}

namespace py = pybind11;

PYBIND11_PLUGIN(example) {
    py::module m("example", "pybind11 example plugin");

    m.def("add", &add, "A function which adds two numbers");

    return m.ptr();
}

person flamelite    schedule 12.07.2017    source источник
comment
Вы оставили проект C ++ пустым? Или вы добавляли какие-либо модули Python, используя что-то вроде PYBIND11_PLUGIN(...) {...}.   -  person pschill    schedule 12.07.2017
comment
Я не использую Pybind, но в целом кажется, что имя вашей функции инициализации и имя вашего модуля (файла) не совпадают.   -  person YiFei    schedule 12.07.2017
comment
Нет, я написал самый простой код на C ++   -  person flamelite    schedule 12.07.2017
comment
@YiFei, не могли бы вы мне немного объяснить, где используется функция init?   -  person flamelite    schedule 12.07.2017
comment
Как называется созданный файл .pyd? Оно должно совпадать с названием модуля, например, example.pyd или example.*.pyd.   -  person pschill    schedule 12.07.2017
comment
Project11.pyd такое же, как у моего проекта   -  person flamelite    schedule 12.07.2017
comment
Можете ли вы переименовать файл в example.pyd и посмотреть, работает ли это?   -  person pschill    schedule 12.07.2017
comment
я сделал это в свойствах конфигурации ›общие› имя цели: $ (пример)   -  person flamelite    schedule 12.07.2017
comment
но я получил эту ошибку: TargetPath (.. \ visual studio 2015 \ Projects \ Project11 \ x64 \ Debug \ .pyd) не соответствует значению свойства OutputFile компоновщика   -  person flamelite    schedule 12.07.2017
comment
Затем вам может потребоваться также изменить Свойства конфигурации ›Компоновщик› Выходной файл. Или просто возьмите Project11.pyd, который был создан ранее, переименуйте его в example.pyd, а затем импортируйте его в python.   -  person pschill    schedule 12.07.2017
comment
Я изменил это как $ (OutDir) $ (example) $ (TargetExt), но теперь я получаю файл .pyd без имени.   -  person flamelite    schedule 12.07.2017


Ответы (1)


В python имя файла .pyd должно совпадать с именем модуля, который находится внутри. Из документации (https://docs.python.org/2/faq/windows.html):

Если у вас есть DLL с именем foo.pyd, тогда она должна иметь функцию initfoo(). Затем вы можете написать Python «import foo», и Python будет искать foo.pyd (а также foo.py, foo.pyc) и, если он его найдет, попытается вызвать initfoo() для его инициализации.

В вашем коде вы создаете модуль python с именем example, поэтому выходной файл должен быть example.pyd.

Редактировать:

В FAQ по pybind11 упоминается несовместимая версия python как еще один возможный источник ошибок (https://pybind11.readthedocs.io/en/stable/faq.html):

ImportError: динамический модуль не определяет функцию инициализации

  1. Убедитесь, что имя, указанное в pybind::module и PYBIND11_PLUGIN, согласовано и идентично имени файла библиотеки расширений. Последний не должен содержать никаких дополнительных префиксов (например, test.so вместо libtest.so).

  2. Если описанное выше не устранило вашу проблему, вероятно, вы используете несовместимую версию Python (например, библиотека расширений была скомпилирована для Python 2, а интерпретатор работает поверх какой-либо версии Python 3, или наоборот)

person pschill    schedule 12.07.2017
comment
Для меня это было именование. Оказывается, он тоже чувствителен к регистру! - person Andy; 01.05.2019