1.anaconda 安装创建环境
conda create --name test_pybind
conda activate test_pybind11
conda install pybind11
2.Qt CMake工程
CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project(testpybind11 LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(PYTHON_EXECUTABLE "C:/Users/93551/.conda/envs/test_pybind11/python.exe")
set(PYTHON_INCLUDE_DIR "C:/Users/93551/.conda/envs/test_pybind11/include")
set(PYTHON_LIBRARY "C:/Users/93551/.conda/envs/test_pybind11/libs")
set(pybind11_DIR "C:/Users/93551/.conda/envs/test_pybind11/Lib/site-packages/pybind11/share/cmake/pybind11")
include_directories(${PYTHON_INCLUDE_DIR})
link_directories(${PYTHON_LIBRARY})
find_package(Python REQUIRED)
find_package(pybind11 REQUIRED)
add_library(testpybind11 SHARED Myclass.cpp TestMyClass.cpp BindPython.cpp)
target_link_libraries(testpybind11 python3.lib python312.lib)
# 后缀名改成pyd能够被python引用,且要去除lib前缀
set_target_properties(testpybind11 PROPERTIES PREFIX "" SUFFIX ".pyd")
MyClass.h
#ifndef MYCLASS_H
#define MYCLASS_H
class MyClass {
public:
MyClass() : value(0) {}
void setValue(int val) { value = val; }
int getValue() { return value; }
int value;
};
#endif // MYCLASS_H
MyClass.cpp
//留空就行
TestMyClass.h
#ifndef TESTMYCLASS_H
#define TESTMYCLASS_H
#include <pybind11-global/pybind11/pybind11.h>
#include <pybind11-global/pybind11/embed.h>
#include <iostream>
namespace py = pybind11;
//测试c++调用自定义的python
int testMyClass()
{
//py::scoped_interpreter guard{}; // 初始化Python解释器
// 导入Python模块
py::module testpybind11_module = py::module::import("testpybind11");
//py::module testpybind11_module = py::module::current();
// 获取Python类的引用
py::object MyCustomClass = testpybind11_module.attr("MyClass");
// 创建Python对象
py::object my_object = MyCustomClass();
my_object.attr("setValue")(10);
// 调用Python方法
auto value = my_object.attr("getValue")().cast<int>();
std::cout << "value:" << value << std::endl;
}
#endif // TESTMYCLASS_H
TestMyClass.cpp
//留空就行
BindPython.cpp
#include <pybind11-global/pybind11/pybind11.h>
#include <pybind11-global/pybind11/eval.h>
#include <pybind11-global/pybind11/embed.h>
namespace py = pybind11;
using namespace py;
#include"MyClass.h"
#include"TestMyClass.h"
PYBIND11_MODULE(testpybind11, m) {
py::class_<MyClass>(m, "MyClass")
.def(py::init<>())
.def("setValue", &MyClass::setValue)
.def("getValue", &MyClass::getValue);
}
3.生成的库文件为testpybind11.pyd,有lib前缀会报错
这一步非常重要,否则报错
ImportError: dynamic module does not define module export function
4.python调用
#测试使用c++类
import testpybind11
my_obj = testpybind11.MyClass()
my_obj.setValue(10)
print(my_obj.getValue())
#测试使用ptyhon类
testpybind11.testMyClass()
5.C++实例化自己创建的python类
CMakeLists.txt
cmake_minimum_required(VERSION 3.5)
project(testpybind11 LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(PYTHON_EXECUTABLE "C:/Users/93551/.conda/envs/test_pybind11/python.exe")
set(PYTHON_INCLUDE_DIR "C:/Users/93551/.conda/envs/test_pybind11/include")
set(PYTHON_LIBRARY "C:/Users/93551/.conda/envs/test_pybind11/libs")
set(pybind11_DIR "C:/Users/93551/.conda/envs/test_pybind11/Lib/site-packages/pybind11/share/cmake/pybind11")
include_directories(${PYTHON_INCLUDE_DIR})
link_directories(${PYTHON_LIBRARY})
find_package(Python REQUIRED)
find_package(pybind11 REQUIRED)
#add_library(testpybind11 SHARED Myclass.cpp TestMyClass.cpp BindPython.cpp)
add_executable(testpybind11
main.cpp
Myclass.cpp TestMyClass.cpp BindPython.cpp
)
target_link_libraries(testpybind11 python3.lib python312.lib)
# 后缀名改成pyd能够被python引用,且要去除lib前缀
#set_target_properties(testpybind11 PROPERTIES PREFIX "" SUFFIX ".pyd")
main.cpp
#include <pybind11-global/pybind11/pybind11.h>
#include <pybind11-global/pybind11/embed.h>
#include <iostream>
namespace py = pybind11;
int main() {
py::scoped_interpreter guard{};
// 导入example模块
py::module testpybind11_module = py::module::import("testpybind11");
//py::module testpybind11_module = py::module::current();
// 获取Python类的引用
py::object MyCustomClass = testpybind11_module.attr("MyClass");
// 创建Python对象
py::object my_object = MyCustomClass();
my_object.attr("setValue")(10);
// 调用Python方法
auto value = my_object.attr("getValue")().cast<int>();
std::cout << "value:" << value << std::endl;
return 0;
}
6.总结
- 一个工程只能有一个PYBIND11_MODULE?
- PYBIND11_MODULE只能写在cpp中?
- 生成的库不能以lib开头