Как я могу собрать расширение C ++ вручную с помощью mingw-w64, Python и pybind11? - PullRequest
1 голос
/ 16 марта 2020

Моя конечная цель - скомпилировать расширение Python C ++ из моего кода C ++. В настоящее время, чтобы начать, я следую простому примеру с первых шагов pybind11 документации. Моя рабочая среда - Windows 7 Professional 64-битная, mingw-w64 (x86_64-8.1.0-posix-seh-rt_v6-rev0) и Anaconda3 с Python 3.7.4 64-битная. У меня есть 2 файла. Первый файл C ++ - пример. cpp

#include <pybind11/pybind11.h>

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

PYBIND11_MODULE(example, m) {
    m.doc() = "pybind11 example plugin"; // optional module docstring

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

Я компилирую файл C ++ с помощью следующей команды:


C:/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/bin/g++.exe -shared -std=c++11 -DMS_WIN64 -fPIC -ID:\Users\ADAS\anaconda3\Include -ID:\Users\ADAS\anaconda3\Library\include -ID:\Users\ADAS\anaconda3\pkgs\python-3.7.4-h5263a28_0\include -Wall -LD:\Users\ADAS\anaconda3\Lib -LD:\Users\ADAS\anaconda3\pkgs\python-3.7.4-h5263a28_0\libs example.cpp -o example.dll -lPython37

Результат компиляции успешен, и я получение example.dll файла.

На следующем шаге я запускаю следующий Python код - example.py:

import example

def main():
    i, j = (1, 2)
    res = example.add(i, j)
    print("%d + %d = %d" % (i, j, res))

if __name__ == '__main__':
    main()

И здесь у меня возникла проблема. Кажется, строка import example не дает мне никаких предупреждений или ошибок, но строка res = example.add(i, j) дает мне ошибку:

AttributeError: module 'example' has no attribute 'add'

В Ubuntu 18.04 я успешно скомпилировал и запустил в Python пример выше но в моем офисе у меня есть только Windows 7.

Вопросы: что не так в моей настройке или командной строке? Можно ли исправить эту проблему без изменения текущего компилятора C ++ (mingw-w64 версии 8.1) в Windows?

1 Ответ

0 голосов
/ 16 марта 2020

Это невероятно! Проблема была только в расширении скомпилированного файла. Как только я изменил .dll на .pyd, пример Python (example.py) работает без проблем!

Итак, новая командная строка:

C:/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/bin/g++.exe -shared -std=c++11 -DMS_WIN64 -fPIC -ID:\Users\ADAS\anaconda3\Include -ID:\Users\ADAS\anaconda3\Library\include -ID:\Users\ADAS\anaconda3\pkgs\python-3.7.4-h5263a28_0\include -Wall -LD:\Users\ADAS\anaconda3\Lib -LD:\Users\ADAS\anaconda3\pkgs\python-3.7.4-h5263a28_0\libs example.cpp -o example.pyd -lPython37

Поскольку я провел несколько экспериментов с аргументами командной строки, я собираюсь снова проверить все аргументы компилятора, чтобы убедиться, что он дает успешный результат. Я сообщу вам, если некоторые изменения все еще требуются.

Обновление 1:

В соответствии с Python3 настройками по умолчанию полное расширение скомпилированного файла C ++ в Windows должно быть .cp37-win_amd64.pyd.

Мы можем получить расширение с помощью команды терминала:

python -c "from distutils import sysconfig; print(sysconfig.get_config_var('EXT_SUFFIX'))"

Это эквивалент python3-config --extension-suffix из документации pybind11. Сценарий python3-config не реализован в среде Windows (по крайней мере, в дистрибутиве Anaconda3).

...