Pybind11使用总结(实现C++与Python互相调用)

Pybind11使用总结(实现C++与Python互相调用)

实验运行环境:
Linux操作系统
C++11
Python 3.7
Cmake 2.8

第一步、编译pybind11

首先从https://github.com/pybind/pybind11 上下载pybind11源码。解压后进入文件夹使用cmake进行编译:

mkdir build
cd build
cmake ..
cmake --build . --config Release  
make   

// 这一步若发生错误查看python是否有pytest包,没有应先进行安装。

以上步骤若正常结束pybind11文件夹下会生成tests文件夹,在该文件夹中若能找到两个.so文件说明编译成功。

第二步 测试用例

1.Python调用C++模块
关于python调用C++官方文档给出了详细的配置方法及函数使用,不再赘述。请参考官网文档https://pybind11.readthedocs.io/en/latest/basics.html

2.C++调用python
C++调用python主要使用embed头文件实现,下文代码默认都有#include

2.1 C++调用python函数
(建议将工程文件放于pybind11同一文件夹下)
工程文件建立:

mkdir pf_test
cd pf_test
touch main.cpp
touch calc.py
Touch CMakelists.txt
mkdir lib

将编译生成的两个.so文件复制到lib文件夹下

下面是一个简单的测试例子

//main.cpp
#include
#include
namespace py=pybind11;
int main() {
py::scoped_interpreter python;
//查看系统路径
py::module sys=py::module::import("sys");
py::print(sys.attr("path"));
//用import函数导入python模块
auto module=py::module::import("calc");
//调用函数时要用attr()进行类型转换
module.attr("add")(1,2);
return 0;
}
//calc.py
def add(i,j)print(“Hi”)
return i+j
//CMakelists.txt
cmake_minimum_required (VERSION 2 .8)
project(pf_test)
SET(CMAKE_CXX_FLAGS "-std=c++11")
#指定自己的python库路径
link_directories(~/anaconda/anaconda3/lib)
#将自己的python头文件包含进来
INCLUDE_DIRECTORIES(~/anaconda/anaconda3/include/python3.7m)
#将自己pybind11头文件路径包含进来
INCLUDE_DIRECTORIES(~/pybind/pybind11-2.3.0/include/pybind11)
#连接到两个动态库文件
link_libraries(/home/wangzq/anaconda/ anaconda3/pkgs/python-3.7.4-h265db76_1/lib/lib/python3.7m.so)
link_libraries(${CMAKE_CURRENT_SOURCE_DIR}/lib/pybind11_cross_ _module_tests.cpython-37m-x86_64-1inux-gnu.so)
link_libraries(${CMAKE_CURRENT_SOURCE_DIR}/1ib/pybind11_tests. cpython-37m-x86_64-1inux-gnu.so)
add_executable(pf_test main.cpp calc.py)

随后将当前工程文件加入python运行路径,有两种方法:
解决:
1.在自己python的site-pkg里添加.pth文件,然后把自己的工程路径写进去
2. vi ~/.bashrc 在bashrc里加如下字段
export PYTHONPATH=/home/wangzq/pybind/pybind11-2.3.0/pf_test:$PATH
//即添加当前工程文件目录,保存退出后执行source ~/.bashrc

以上操作结束后即可编译运行:
mkdir build
cd build
cmake …
make
生成可执行文件

2.2调用python类

工程文件结构:

所有配置操作与2.1中相同,具体代码实现如下:

//mian.cpp
#include 
#include 
#include
namespace py=pybind11;
int main() {
py::scoped_ interpreter python;
py::print ("hello world") ;
//用py::object导入python类模块并进行类的初始化
py::object Dog=py: :module: :import("c_ test") .attr ("Dog") ;
py::object obj=Dog ("miao", "sit") ;
// function_ test
py::object add=obj.attr ("add") ;
py::object result2=add(2,4) ;
//注:python返回值到c++中需要类型转换,用cast<数据类型>()来进行转换
int n=result2.cast<int> () ;
std::cout<<n<<std: :endl ;
//list_ test  集合类型
py::object type_ test=obj.attr ("type_ test") ;
py::object result3=type_ test (2) ;
py::list v[5]=result3.cast<py: :list>() ;
std::cout<<v[2]<<std: :endl ; .
std:: cout<<v<<std: :endl;
//dict_ test   字典类型
py::object dict_ test=obj .attr ("dict_ test") ;
py::object result4=dict_ test (1) ;
py::dict dd=result4.cast<py: :dict>() ;
std::cout<<dd<<std: :endl;
//set_ test  列表类型
py::object set_ test=obj .attr ("set_ test") ;
py::object result5=set_ test(3) ;
py::set ss=result5.cast<py: :set>() ;
std::cout<<ss<<std: :endl;
//tuple_ test  元组类型测试
py::object tup1e_test=obj .attr ("tuple_test") ;
py::object result 6=tuple_test (1) ;
Py::tuple tt=result6.cast<py: : tuple> () ;
std::cout<<tt<<std: :endl ;
return 0;
}
//c_test.py
class Dog():
def  init__ (self, name, action) :
self.name=name
self.action=action
def get_ name (self) :
return  self._ name
def get_ action(self) :
return self .action
def add(self,i,j) :
print ("Hi ") 
return i+j
def type_ test (self,a) :
n=list ()
if a==1:
n={1,2, 3}
else :
n={5,5,5}
print ("type test")
return n
def  dict_ test (self,b) :
d=dict ()
If b==1:
d={"wo":2, "ni":3}
else :
d={"hei" :3, "ha":5}
return d
def set_ test (self,c) :
e=set ()
if c==1:
e={1,2,3,3}
else :
e={2,3,3,3}
return e
def tuple_ test(self,d) :
f=tup1e()
if d==1:
f=(5, 6, 7)
        else:
            f=(7,8,9)
        return  f
//注意换行 格式乱了。。。

CMakelists与2.1的CMakelists除项目名外基本相同
编译运行即可

参考: https://pybind11.readthedocs.io/en/stable/advanced/embedding.html
https://www.dazhuanlan.com/2020/03/24/5e7954b2e8842/

你可能感兴趣的:(一只间接性努力的码农,c++,python,cmake)