簡體   English   中英

如何使用 mingw-w64、Python 和 pybind11 手動構建 C++ 擴展?

[英]How can I build manually C++ extension with mingw-w64, Python and pybind11?

我的最終目標是從我的 C++ 代碼編譯 Python 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++ 文件——example.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。

問題:我的設置或命令行有什么問題? 是否可以在不更改 Windows 下當前的 C++ 編譯器(mingw-w64 版本 8.1)的情況下解決此問題?

真是難以置信! 問題只是編譯文件的文件擴展名。 一旦我將.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 默認設置,Windows 下編譯的 C++ 文件的完整擴展名必須是.cp37-win_amd64.pyd

我們可以通過終端命令獲取擴展名:

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

這相當於 pybind11 文檔中的python3-config --extension-suffix python3-config腳本未在 Windows 環境中實現(至少在 Anaconda3 發行版中)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM