Cython

pybind11快速实现c,c++ 与 python互通

2022-01-28  本文已影响0人  python测试开发

简介

pybind11是一个轻量级的头文件库, 为Python和C、C++实现了类型互通,主要用于为现有C++代码创建Python绑定。它的目标和语法与Boost.Python库相似:通过使用编译时自省来推断类型信息,最大限度地减少传统扩展模块中的模板代码。

Boost是一个庞大而复杂的实用程序库套件,几乎可以与现存的所有C++编译器一起使用。这种兼容性是有代价的:为了支持最古老和最有问题的编译器,必须使用神秘的模板技巧和变通方法。现在与C++11兼容的编译器已经广泛使用,Boost已经包含过于庞大和不必要的依赖。

pybind11是Boost.Python的精简版本,剥离了所有与绑定生成无关的东西。在没有注释的情况下,核心头文件只需要大约4K行代码,并且依赖于Python(2.7或3.5+,或PyPy)和C++标准库。这种紧凑的实现是由于一些新的C++11语言特性(特别是:tuple、lambda函数和变量模板)而实现的。

教程和参考文档在https://pybind11.readthedocs.io/en/latest/提供。源代码可以在https://github.com/pybind/pybind11/获得。

核心功能

以下核心C ++功能可以映射到Python

其他有用功能

快速入门

调试环境:ubuntu 20.04.3 LTS

# pip install pybind11
# git clone https://github.com/pybind/pybind11
# cd pybind11/include

创建文件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 that adds two numbers");
}

编译执行

#  c++ -O3 -Wall -shared -std=c++11 -fPIC $(python3 -m pybind11 --includes) example.cpp -o example$(python3-config --extension-suffix)
# ls
example.cpp  example.cpython-38-x86_64-linux-gnu.so  pybind11
# python
Python 3.8.8 (default, Apr 13 2021, 19:58:26) 
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import example
>>> example.add(1, 2)
3

在c++中调用python

demo.cpp

#include <iostream>
#include <pybind11/embed.h>

namespace py = pybind11;
using namespace std;

int main()
{
    cout << "Hello PyBind World" << endl;

    // start the interpreter and keep it alive
    py::scoped_interpreter guard{}; 
    py::module math = py::module::import("math");
    py::object result = math.attr("sqrt")(25);
    std::cout << "Sqrt of 25 is: " << result.cast<float>() << std::endl;
}

新建CMakeLists.txt

project(pybind_demo)
cmake_minimum_required(VERSION 3.13)
set(CMAKE_CXX_STANDARD 14)  

include(FetchContent)
FetchContent_Declare(
    pybind11
    GIT_REPOSITORY https://github.com/pybind/pybind11.git
    GIT_TAG        v2.6.2
    GIT_SHALLOW    TRUE
)

FetchContent_MakeAvailable(pybind11)

add_executable(demo demo.cpp)
target_link_libraries(demo PRIVATE pybind11::embed)

编译执行:

$ cmake .
CMake Warning (dev) at CMakeLists.txt:1 (project):
  Policy CMP0048 is not set: project() command manages VERSION variables.
  Run "cmake --help-policy CMP0048" for policy details.  Use the cmake_policy
  command to set the policy and suppress this warning.

  The following variable(s) would be set to empty:

    CMAKE_PROJECT_VERSION
    CMAKE_PROJECT_VERSION_MAJOR
    CMAKE_PROJECT_VERSION_MINOR
    CMAKE_PROJECT_VERSION_PATCH
This warning is for project developers.  Use -Wno-dev to suppress it.

-- pybind11 v2.6.2 
-- Configuring done
-- Generating done
-- Build files have been written to: /home/andrew/code/pybind11/include
$ make
Scanning dependencies of target demo
[ 50%] Building CXX object CMakeFiles/demo.dir/demo.cpp.o
[100%] Linking CXX executable demo
[100%] Built target demo
$ ./demo 
Hello PyBind World
Sqrt of 25 is: 5

以上步骤需要保证对github的访问。参考资料:https://blog.devgenius.io/calling-python-and-c-code-using-pybind-99ab7fefa685

在python中调用c++

example.cpp

#include <pybind11/embed.h>

int multiply(int i, int j) {
    return i * j;
}

PYBIND11_MODULE(example, m) {
    m.doc() = "pybind11 example plugin"; // optional module docstring
    m.def("multiply", &multiply, "A function which multiplies two numbers");
}

新建CMakeLists.txt

cmake_minimum_required(VERSION 3.13)
project(pybind_demo)
set(CMAKE_CXX_STANDARD 14)  

include(FetchContent)
FetchContent_Declare(
    pybind11
    GIT_REPOSITORY https://github.com/pybind/pybind11.git
    GIT_TAG        v2.6.2
    GIT_SHALLOW    TRUE
)

FetchContent_MakeAvailable(pybind11)

pybind11_add_module(example example.cpp)
target_compile_features(example PUBLIC cxx_std_14)
set_target_properties(example PROPERTIES SUFFIX ".so")

编译执行:

$ cmake .
-- pybind11 v2.6.2 
-- Configuring done
-- Generating done
-- Build files have been written to: /home/andrew/code/pybind11/include/exmaple
$ make
Scanning dependencies of target example
[ 50%] Building CXX object CMakeFiles/example.dir/example.cpp.o
[100%] Linking CXX shared module example.so
[100%] Built target example
$ ls
CMakeCache.txt  CMakeFiles  cmake_install.cmake  CMakeLists.txt  _deps  example.cpp  example.so  Makefile
$ python
Python 3.8.8 (default, Apr 13 2021, 19:58:26) 
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import example
>>> example.multiply(3, 2)
6
上一篇下一篇

猜你喜欢

热点阅读