编译一时爽,环境火葬场
因为使用A*算法对于路径的寻找需要更高的效率,很明显,python自身完全不能满足我们的需求,因此使用C++编写python扩展变得非常重要.
不幸的是,我昨天花了整整一天都没有解决这个问题,但是今天却进行的异常顺利,下面我来讲一下在使用C++编写python中的几个坑
准备
我们使用的是pybind
的库,具体pybind
应当如何使用在这里我就不过多介绍了,下面先贴出来我用做测试的代码:
1 |
|
需要注意将安装好的pybind11
中的include
文件夹的pybind11
文件夹拷贝到工程文件夹中.
使用g++直接编译
接下来就到了万恶的编译环节,首先,我看见文档里面直接给g++
编译的命令
1 | g++ -O3 -march=native -Wall -shared -std=c++11 -fPIC `python3 -m pybind11 --includes` test.cpp -o test `python3-config --extension-suffix` |
这个命令看起来很简单,但是存在一个问题,里面依赖python-config
命令的输出,但是众所周知,这个命令只有在Linux下才能使用.
我再一次感觉到了windows开发的险恶
使用CMake编译
接下来,我看到网上说cmake
可以进行编译,这样看起来挺好,然而暗藏杀机.
因为cmake
也需要类似于python-config
的环境,然后虽然我安装mingw
确实来了一个python-config
但是这会导致我编译工具链使用的是MS的产品,但是采用的解释器却是GCC编译的.
中间省略了因为使用
anaconda
而不得不一步步教cmake
如何找到我的pybind
的过程
然后这就带来一个完全爆炸.pyd
文件,这个pyd
在mingw
里面的python不认,然后到了conda
里面的python直接提示我dll丢失.
你以为我没查Google,直接提示你:“你安装的库可能有误,建议卸载重装”
我自己写的库怎么卸载重装
但是如果我换做mingw
编译,则更加刺激,直接python给我闪退了
我拿
windbg
查了一下,是内存冲突,但是别的我也不知道了
使用setup.py
编译
这种方法看起来简单,但是结果和那CMake
一样
简而言之,我电脑的状态就是这样:
- 使用windows操作系统
- 卸载了
VisualStudio
- 装了
mingw
- 使用
anaconda
管理python环境
直接buff叠满,能做出来才有鬼.
使用cppimport
这是我目前看到的最好的方法来处理这个问题,源网页
使用这个的好处在于反正我编译出来成功了
这个库用法并不复杂,首先是在文件开头需要添加一行注释
1 | // cppimport |
然后在文件的末尾需要有
1 | /* |
这实际上是一段Mako
块,这一部分的python代码将会被运行
其中第一行是由于多文件编译,指定除了这个文件外的另外源文件
第二行则是使用相关的编译选项
cppimport
调用
虽然cppimport
支持实时调用(每次import
)的时候预编译,但是这么做对我们来讲没有必要,我们可以采用cppimport
的预编译方式(就是pyd
)实现
使用以下代码
1 | python -m cppimport build pytest.cpp |
虽然理论上没有
pytest.cpp
也可以自动检测,但是我们不可避免会带有Unicode
字符,然后就出错了