主要整理c/c++ call python 以及 python call c/c++ 的基本使用。
prerequisite
how python search the package when import module
The main logic is to build the c/c++ code into the .so
file and add the .so
into the search file of the python package. How to check the python search path?
import sys |
If we modify the environment variable export PYTHONPATH=<path_for_so_file>
, this path will be added into the sys.path
If we want to show the path for specific module, we could use
import numpy |
关于cpython,pybind11,swig
参考这个
https://www.zhihu.com/question/323926607
显而易见,使用pybind11是当前主流的方式
one important thing before linking
to detect if the current version of python, not mattter for python2 or python3 is static (with the suffix of .a) or the dynamic (with the suffix of .so) is important thing. Since it requires different operations to link the packages. the fpic
and enable shared
parameters are necessary for linking into a shared python libraray. Check this discussion to get more details:
https://discourse.paraview.org/t/undefined-symbol-pyexc-valueerror/5494/4
In this case, the python library is not linked firstly, then we set particular options as OFF, the python library is failed to link with the other binaries because it did not compiled by the fpic label.
this is an example of embed python into the c++ manually:
cpp file: |
and the python file:
import socket |
compile by the cmake:
cmake_minimum_required (VERSION 3.14) |
compile by the g++ manually
g++ $(python-config --cflags) -o GetHostname $(python-config --ldflags) ../GetHostname.cc |
The running reuslts looks like this:
$ ./GetHostname |
call c/c++ code in python
use pybind11
It is straight forward with the help of the pybind11 and the documents online is clear with sample code.
call python from the c/c++ code
use pybind11
using embed to put the intepreter in c/c++
use cpython
official documents:
https://docs.python.org/2/extending/embedding.html
即使使用了pybind11,最后编译成的.so文件还是cpython的
关于一个实际bug的解决
具体可以参考这个
最终的原因是由于一个函数和系统的函数命名一样了,导致的这个错误 (不使用namespace的缺点)
虽然仅仅知道怎么解决,还不知道原因为什么是这样,但这个过程有一些收获
比如知道如何来查看cpython的代码 然后怎么通过对应的版本来互相匹配 找到正确的分支 比如看这里 比如知道了cpython的实现里 dprintf是被重新定义过的 没有使用库函数的那个dprintf 需要查看底层的打印信息的话 需要重新编译python然后需要加上哪些环境变量 比如参考这个.
然后要把c和系统的东西再更上一层楼的话 看看Cpython的实现是一个不错的途径 reference中也列出了一些资料
然后对namespace又有了一些新的认识 像这种case 使用 namespace 就不容易出现类似的问题了 或者有良好的命名习惯 一个project中的函数都使用特定的前缀开始
然后从c/c++ call python的时候 首先保证python自己是可以正常运行 通过python 可以正常进行import操作,以及python的module是可以被load 的。
关于mpi4Py
use mpi4py with pybind11
https://stackoverflow.com/questions/49259704/pybind11-possible-to-use-mpi4py
download and compile mpi4py 之前 注意使用module check 到底是 openmpi还是mpich 保证编译和执行的时候使用的是一种mpi的实现
https://groups.google.com/forum/#!topic/mpi4py/jPqNrr_8UWY
https://mpi4py.readthedocs.io/en/stable/tutorial.html#wrapping-with-swig
source code
wrap with python
https://mpi4py.readthedocs.io/en/stable/tutorial.html#wrapping-with-swig
https://stackoverflow.com/questions/12459906/how-to-pass-mpi-information-to-ctypes-in-python
https://stackoverflow.com/questions/12459906/how-to-pass-mpi-information-to-ctypes-in-python
Attempting to use an MPI routine before initializing MPICH
https://bitbucket.org/mpi4py/mpi4py/issues/107/compiling-problem-for-swig-demo
get numpy array from python
//sample code at the cpp end |
//code at the python end |
For compiling, juse use the add_executable
. The .cmake configuration will be generated after the build and install for the bybind
cmake_minimum_required(VERSION 2.8.12) |
reference
关于CPython的实现
https://devguide.python.org/exploring/
http://news.51cto.com/art/201712/560631.htm
https://www.zhihu.com/question/23003213
http://note.qidong.name/2018/01/call-cpp-in-python/
pybind tutorial
https://pybind11.readthedocs.io/en/stable/basics.html
simple example of array sum
https://stackoverflow.com/questions/49582252/pybind-numpy-access-2d-nd-arrays
pybind send paramerter to python for any cpp end(arbitrary Python types)
https://pybind11.readthedocs.io/en/stable/reference.html
comparing cpython with pybind11
http://blog.behnel.de/posts/cython-pybind11-cffi-which-tool-to-choose.html