python - 如何使用mingw-w64,Python和pybind11手动构建C++扩展?

标签 python c++ windows mingw-w64 pybind11

我的最终目标是从我的C++代码编译Python C++扩展。目前,我要开始学习pybind11文档的第一步中的一个简单示例。我的工作环境是Windows 7 Professional 64位,mingw-w64(x86_64-8.1.0-posix-seh-rt_v6-rev0)和带有Python 3.7.4 64位的Anaconda3。我有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等效。在Windows环境中(至少在Anaconda3发行版中)未实现python3-config脚本。

关于python - 如何使用mingw-w64,Python和pybind11手动构建C++扩展?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60699002/

相关文章:

.net - 在没有垃圾邮件或拒绝问题的情况下发送开发中的测试电子邮件

java - 这是什么服务器端编程语言?

python - 您可以从 Windows 符号链接(symbolic link)导入 Python 模块吗?

python mysql删除语句不起作用

c++ - Linux C++ : How to properly use template specializations across multiple files?

c++ - Opencv 复制 3 channel IplImage 到 4 channel IplImage

c++ - Cygwin + windows 10 错误 "sigfillset was not declared in the scope"

python - 如何阅读行中的特定单词?

C++ 文件输入/输出

c++ - 如何判断虚拟内存页是否已被锁定?