mingw(Qt) 利用pybind11实现c++与python交互

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.总结

  1. 一个工程只能有一个PYBIND11_MODULE?
  2. PYBIND11_MODULE只能写在cpp中?
  3. 生成的库不能以lib开头
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值