PyBind11 — ошибки компиляции из нескольких файлов библиотек

Недавно я создал код на C++, который хотел бы использовать в Python, поэтому я выбрал PyBind11, так как он казался простым. Поскольку я никогда не работал с этим инструментом, я сначала хотел понять и опробовать базовый пример, приведенный в документации:

https://pybind11.readthedocs.io/en/latest/basics.html

// file test.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 that adds two numbers");
}

Я работаю над Windows 10 с Anaconda, и у меня установлены cygwin и Visual Studio 2022. Я создал env и установил все необходимые пакеты с помощью pip.

Во-первых, я хотел использовать компилятор gcc (cygwin) и нашел это, чтобы установить флаги компилятора: Как мне вручную собрать расширение C++ с помощью mingw-w64, Python и pybind11?

Я попытался скомпилировать код с помощью следующей команды: c++ -shared -std=c++23 -fPIC -IC:\Users\blindschleiche\Anaconda3\envs\feb2023\Include -IC:\Users\blindschleiche\Anaconda3\envs\feb2023\lib\site-packages\pybind11\include -Wall -LC:\Users\blindschleiche\anaconda3\Lib test.cpp -LC:\Users\blindschleiche\Anaconda3\pkgs\python-3.8.16-h6244533_2\libs -o test.pyd -lPython38

Но я получаю кучу ошибок, связанных с файлами библиотеки Python. Конечно, я никогда не менял эти файлы самостоятельно. И некоторые ошибки кажутся "неправильными". Вот полное сообщение об ошибке:

In file included from C:\Users\blindschleiche\Anaconda3\envs\feb2023\Include/Python.h:156,
                 from C:\Users\blindschleiche\Anaconda3\envs\feb2023\lib\site-packages\pybind11\include/pybind11/detail/../detail/common.h:266,
                 from C:\Users\blindschleiche\Anaconda3\envs\feb2023\lib\site-packages\pybind11\include/pybind11/detail/../attr.h:13,
                 from C:\Users\blindschleiche\Anaconda3\envs\feb2023\lib\site-packages\pybind11\include/pybind11/detail/class.h:12,
                 from C:\Users\blindschleiche\Anaconda3\envs\feb2023\lib\site-packages\pybind11\include/pybind11/pybind11.h:13,
                 from test.cpp:1:
C:\Users\blindschleiche\Anaconda3\envs\feb2023\Include/fileutils.h:79:5: error: '__int64' does not name a type; did you mean '__int64_t'?
   79 |     __int64 st_size;
      |     ^~~~~~~
      |     __int64_t
In file included from /usr/include/sys/stat.h:22,
                 from C:\Users\blindschleiche\Anaconda3\envs\feb2023\Include/pyport.h:245,
                 from C:\Users\blindschleiche\Anaconda3\envs\feb2023\Include/Python.h:63,
                 from C:\Users\blindschleiche\Anaconda3\envs\feb2023\lib\site-packages\pybind11\include/pybind11/detail/../detail/common.h:266,
                 from C:\Users\blindschleiche\Anaconda3\envs\feb2023\lib\site-packages\pybind11\include/pybind11/detail/../attr.h:13,
                 from C:\Users\blindschleiche\Anaconda3\envs\feb2023\lib\site-packages\pybind11\include/pybind11/detail/class.h:12,
                 from C:\Users\blindschleiche\Anaconda3\envs\feb2023\lib\site-packages\pybind11\include/pybind11/pybind11.h:13,
                 from test.cpp:1:
C:\Users\blindschleiche\Anaconda3\envs\feb2023\Include/fileutils.h:80:12: error: expected ';' at end of member declaration
   80 |     time_t st_atime;
      |            ^~~~~~~~
C:\Users\blindschleiche\Anaconda3\envs\feb2023\Include/fileutils.h:80:12: error: expected unqualified-id before '.' token
   80 |     time_t st_atime;
      |            ^~~~~~~~
C:\Users\blindschleiche\Anaconda3\envs\feb2023\Include/fileutils.h:82:12: error: expected ';' at end of member declaration
   82 |     time_t st_mtime;
      |            ^~~~~~~~
C:\Users\blindschleiche\Anaconda3\envs\feb2023\Include/fileutils.h:82:12: error: expected unqualified-id before '.' token
   82 |     time_t st_mtime;
      |            ^~~~~~~~
C:\Users\blindschleiche\Anaconda3\envs\feb2023\Include/fileutils.h:84:12: error: expected ';' at end of member declaration
   84 |     time_t st_ctime;
      |            ^~~~~~~~
C:\Users\blindschleiche\Anaconda3\envs\feb2023\Include/fileutils.h:84:12: error: expected unqualified-id before '.' token
   84 |     time_t st_ctime;
      |            ^~~~~~~~
In file included from test.cpp:1:
C:\Users\blindschleiche\Anaconda3\envs\feb2023\lib\site-packages\pybind11\include/pybind11/pybind11.h: In member function 'char* pybind11::cpp_function::strdup_guard::operator()(const char*)':
C:\Users\blindschleiche\Anaconda3\envs\feb2023\lib\site-packages\pybind11\include/pybind11/pybind11.h:76:36: error: 'strdup' was not declared in this scope; did you mean 'strcmp'?
   76 | #    define PYBIND11_COMPAT_STRDUP strdup
      |                                    ^~~~~~
C:\Users\blindschleiche\Anaconda3\envs\feb2023\lib\site-packages\pybind11\include/pybind11/pybind11.h:324:23: note: in expansion of macro 'PYBIND11_COMPAT_STRDUP'
  324 |             auto *t = PYBIND11_COMPAT_STRDUP(s);
      |                       ^~~~~~~~~~~~~~~~~~~~~~
C:\Users\blindschleiche\Anaconda3\envs\feb2023\lib\site-packages\pybind11\include/pybind11/pybind11.h: In member function 'void pybind11::cpp_function::initialize_generic(pybind11::cpp_function::unique_function_record&&, const char*, const std::type_info* const*, pybind11::size_t)':
C:\Users\blindschleiche\Anaconda3\envs\feb2023\lib\site-packages\pybind11\include/pybind11/pybind11.h:76:36: error: 'strdup' was not declared in this scope; did you mean 'strcmp'?
   76 | #    define PYBIND11_COMPAT_STRDUP strdup
      |                                    ^~~~~~
C:\Users\blindschleiche\Anaconda3\envs\feb2023\lib\site-packages\pybind11\include/pybind11/pybind11.h:610:46: note: in expansion of macro 'PYBIND11_COMPAT_STRDUP'
  610 |             = signatures.empty() ? nullptr : PYBIND11_COMPAT_STRDUP(signatures.c_str());
      |                                              ^~~~~~~~~~~~~~~~~~~~~~
C:\Users\blindschleiche\Anaconda3\envs\feb2023\lib\site-packages\pybind11\include/pybind11/pybind11.h: In member function 'pybind11::class_<type_, options>& pybind11::class_<type_, options>::def_property_static(const char*, const pybind11::cpp_function&, const pybind11::cpp_function&, const Extra& ...)':
C:\Users\blindschleiche\Anaconda3\envs\feb2023\lib\site-packages\pybind11\include/pybind11/pybind11.h:76:36: error: there are no arguments to 'strdup' that depend on a template parameter, so a declaration of 'strdup' must be available [-fpermissiv
]
   76 | #    define PYBIND11_COMPAT_STRDUP strdup
      |                                    ^~~~~~
C:\Users\blindschleiche\Anaconda3\envs\feb2023\lib\site-packages\pybind11\include/pybind11/pybind11.h:1781:33: note: in expansion of macro 'PYBIND11_COMPAT_STRDUP'
 1781 |                 rec_fget->doc = PYBIND11_COMPAT_STRDUP(rec_fget->doc);
      |                                 ^~~~~~~~~~~~~~~~~~~~~~
C:\Users\blindschleiche\Anaconda3\envs\feb2023\lib\site-packages\pybind11\include/pybind11/pybind11.h:76:36: note: (if you use
-fpermissive', G++ will accept your code, but allowing the use of an undeclared name is deprecated)
   76 | #    define PYBIND11_COMPAT_STRDUP strdup
      |                                    ^~~~~~
C:\Users\blindschleiche\Anaconda3\envs\feb2023\lib\site-packages\pybind11\include/pybind11/pybind11.h:1781:33: note: in expansion of macro 'PYBIND11_COMPAT_STRDUP'
 1781 |                 rec_fget->doc = PYBIND11_COMPAT_STRDUP(rec_fget->doc);
      |                                 ^~~~~~~~~~~~~~~~~~~~~~
C:\Users\blindschleiche\Anaconda3\envs\feb2023\lib\site-packages\pybind11\include/pybind11/pybind11.h:76:36: error: there are no arguments to 'strdup' that depend on a template parameter, so a declaration of 'strdup' must be available [-fpermissiv
]
   76 | #    define PYBIND11_COMPAT_STRDUP strdup
      |                                    ^~~~~~
C:\Users\blindschleiche\Anaconda3\envs\feb2023\lib\site-packages\pybind11\include/pybind11/pybind11.h:1789:33: note: in expansion of macro 'PYBIND11_COMPAT_STRDUP'
 1789 |                 rec_fset->doc = PYBIND11_COMPAT_STRDUP(rec_fset->doc);
      |

Просто, например, сосредоточьтесь на ошибках, упомянутых для «fileutils.h»:

C:\Users\blindschleiche\Anaconda3\envs\feb2023\Include/fileutils.h:80:12: error: expected ';' at end of member declaration
   80 |     time_t st_atime;
      |            ^~~~~~~~
C:\Users\blindschleiche\Anaconda3\envs\feb2023\Include/fileutils.h:80:12: error: expected unqualified-id before '.' token
   80 |     time_t st_atime;
      |            ^~~~~~~~
C:\Users\blindschleiche\Anaconda3\envs\feb2023\Include/fileutils.h:82:12: error: expected ';' at end of member declaration
   82 |     time_t st_mtime;
      |            ^~~~~~~~
C:\Users\blindschleiche\Anaconda3\envs\feb2023\Include/fileutils.h:82:12: error: expected unqualified-id before '.' token
   82 |     time_t st_mtime;
      |            ^~~~~~~~
C:\Users\blindschleiche\Anaconda3\envs\feb2023\Include/fileutils.h:84:12: error: expected ';' at end of member declaration
   84 |     time_t st_ctime;
      |            ^~~~~~~~
C:\Users\blindschleiche\Anaconda3\envs\feb2023\Include/fileutils.h:84:12: error: expected unqualified-id before '.' token
   84 |     time_t st_ctime;
      |            ^~~~~~~~

и сравните ошибки с фактическим кодом в файле:

// fileutils.h, line 70 onwards
#ifdef MS_WINDOWS
struct _Py_stat_struct {
    unsigned long st_dev;
    uint64_t st_ino;
    unsigned short st_mode;
    int st_nlink;
    int st_uid;
    int st_gid;
    unsigned long st_rdev;
    __int64 st_size;
    time_t st_atime;
    int st_atime_nsec;
    time_t st_mtime;
    int st_mtime_nsec;
    time_t st_ctime;
    int st_ctime_nsec;
    unsigned long st_file_attributes;
    unsigned long st_reparse_tag;
};
#else
#  define _Py_stat_struct stat
#endif

Нет ни точки с запятой, ни токена .. Так что я не понимаю, в чем причины этой ошибки или кто-то уже сталкивался с такими проблемами. Я пытался найти информацию об этой проблеме, но большинство вопросов, касающихся этой темы, касаются «отсутствующего файла python.h», а не некоторых ошибок компиляции.

Кто-нибудь знает, как решить эту ошибку? Или у кого-то есть опыт использования PyBind11 в системе Windows?

Я думал, что эти команды одинаковы?

Blindschleiche 24.05.2023 15:08

Да, я ошибся.

Karen Baghdasaryan 24.05.2023 15:09
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
2
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

__int64 в _Py_stat_struct — это целочисленный тип размера, специфичный для Microsoft. Следовательно, компилятор gcc не может его декодировать, потому что он не знает о таком типе. Чтобы правильно скомпилировать файлы, вы должны использовать компилятор Microsoft.

Спасибо за информацию, я не знал об этом. У вас есть опыт использования компилятора Microsoft в сочетании с PyBind, и вы можете привести минимальный пример?

Blindschleiche 24.05.2023 15:04

К сожалению, у меня нет опыта использования компилятора Microsoft в сочетании с PyBind. Но я нашел эту ссылку, которая может вам помочь learn.microsoft.com/en-us/visualstudio/python/…

Karen Baghdasaryan 24.05.2023 15:09

Другие вопросы по теме