Python call CPlus

Pybind11 Python C++

环境安装

1
conda install pybind11 -c conda-forge

绑定一个c++的类

文件结构

1
2
3
src/Person.cpp
    /Person.h
    /p_person.cpp # pybind文件

Person.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//Persion.cpp
#include "Person.h"

Person::Person() {
name = "";
age = 0;
}

Person::Person(string name, int age) {
this->name = name;
this->age = age;
}

Person::~Person() {

}

string Person::say_hello() {
return "hello, my name is " + this->name;
}

void Person::set_name(string name) {
this->name = name;
}
void Person::set_age(int age) {
this->age = age;
}

string Person::get_name() const {
return this->name;
}

int Person::get_age() const {
return this->age;
}

Person.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Persion.h
#pragma once

#include <string>
using namespace std;

class Person {
public:
Person();
Person(string name, int age);
~Person();

void set_name(string name);
void set_age(int age);
string get_name() const;
int get_age() const;

string say_hello();


private:
string name;
int age;

};

p_person.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include "Person.h"

namespace py = pybind11;

PYBIND11_MODULE(person, m)
{
m.doc() = "Person module"; // optional module docstring

py::class_<Person>(m, "Person")
.def(py::init<>())
.def("get_name", &Person::get_name)
.def("set_name", &Person::set_name)
.def("get_age", &Person::get_age)
.def("set_age", &Person::set_age)
// .def("get_gender", &Person::get_gender)
// .def("set_gender", &Person::set_gender)
.def("say_hello", &Person::say_hello);
}

CMakeList.txt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# CMakeLists.txt
cmake_minimum_required(VERSION 3.10)

project(PythonCPPExample)

# set(CMAKE_CXX_STANDARD 17)

# add_executable(PythonCPPExample main.cpp)

# find_package(<PackageName> [version] [EXACT] [QUIET] [MODULE]
set(PYTHON_EXECUTABLE /root/anaconda3/envs/pytorch_1.7.1_cu92/bin/python3.8)
set(PYTHON_INCLUDE_DIR /root/anaconda3/envs/pytorch_1.7.1_cu92/include/python3.8)
set(PYTHON_LIBRARY /root/anaconda3/envs/pytorch_1.7.1_cu92/lib/libpython3.8.so)

find_package(PythonLibs 3 REQUIRED )
# 这个文件很重要
set(pybind11_DIR /root/anaconda3/envs/pytorch_1.7.1_cu92/share/cmake/pybind11/ ) # lib/python3.8/site-packages/pybind11 )
find_package(pybind11 REQUIRED)

message(STATUS " -XX- LIb path: ${PYTHON_INCLUDE_DIRS}")
message(STATUS " -XX- LIb path: ${pybind11_DIR}")
message(STATUS " -XX- LIb path: ${pybinSHARED ")

# add_subdirectory(src)

Pybind11_add_module(person
src/Person.cpp
d11_INCLUDE_DIRS}")

# .h 头文件路径
# include_directories(
# ${PYTHON_INCLUDE_DIRS}
# './src/'
# ${pybind11_INCLUDE_DIRS}
# )


# 库生成(动态SHARED,静态STATIC)
# add_library(person src/p_person.cpp)

# 目标文件依赖库
# target_link_libraries(person ${PYTHON_LIBRARIES} pybind11::pybind11)

# install(TARGETS person DESTINATION ${PYTHON_INSTALL_DIR}/site-packages/ )

编译

1
2
3
4
mkdir build
cd build
cmake ..
make

最终得到文件

person.cpython-38-x86_64-linux-gnu.so

python Call

  1. 当前环境下 CMakefile的环境下运行
1
2
3
4
5
6
7
8
9

import person

if __name__ == '__main__':
a = person.Person()
# a = person.Person('Tom', 18)
a.set_name("Tom")
a.set_age(19)
print(a.say_hello())

2、换个环境下运行

  • (此demo)只需要python版本一致,即可运行

ref

Python 中如何使用pybind11调用C++_pybind11 python调用c++-CSDN博客

pybind11:实现Python调用C++代码(入门)-CSDN博客