当前位置: 首页 > news >正文

开发笔记之:python集成Qt C++编写的扩展模块

一、问题列表

(1)C++定义的类(class)/结构体(struct)如何被python所“理解”
(2)如何了解扩展模块(.pyd)的依赖 以及 添加依赖目录
(3)指针的传递 和 管理
(4)字节数组的传递
(5)“no QGuiApplication instance and no application …”
(6)QGraphicsScene初始化问题

二、结论

(1)pybind11支持定义组合类型class/struct。
而且class/struct的项既可以是简单类型,也可以是组合类型。组合类型需要提前被定义。
(注:本项主要需改造C++端,python端对应即可)
(2.1)使用VS工具 dumpbin 来解析 .pyd 文件的依赖。(注:仅适用于windows平台)
(2.2)使用 os 的 add_dll_directory 方法来添加所依赖的 dll 所在的目录。例如添加 Qt的安装目录下的bin目录。(注:只在python端)
(3)暂时还没搞明白。
(注:使用场景:在python端发起创建句柄,调用方法中传入句柄)
(4)使用 py::buffer 类型接收,再转换成 uchar *。(主要在C++端)
(5)在模块入口构造 QGuiApplication 实例。(主要在C++端)
(6)将(5)中的 改成 QGuiApplication 改成 QApplication。
因为其属性font 依赖于 QApplication::font。(主要在C++端)

三、代码

(1)定义 & 绑定 结构体/实体类

  a. 结构体定义(c++)

typedef struct foo_1 {int field1;bool field2;std::string fileld3;
} FOO_1;

  b. 绑定结构体/类定义(c++, pybind11)

py::class_<FOO_1>(m, "FOO_1").def(py::init<>()).def_readwrite("field1", &FOO_1::field1).def_readwrite("field2", &FOO_1::field2).def_readwrite("fileld3", &FOO_1::fileld3);

  c.引用结构体/类类型(python)

。。。
import module1 as md1
。。。
foo1 = md1.FOO_1()
foo1.field1 = 999
foo1.field2 = True
foo1.fileld3 = "hello, world"
。。。

(2.1)列出 pyd 文件的依赖(windows环境、VS开发环境、cmd)

"C:\Program Files (x86)\Microsoft Visual Studio\
2019\Community\VC\Tools\MSVC\14.29.30133\
bin\Hostx64\x64\dumpbin.exe" /DEPENDENTS module1.pyd

(2.2)添加 Qt 环境到 dll 目录(python)

import os
os.add_dll_directory("C:/Qt/5.15.10/msvc2019_64/bin")

(3)指针的使用

  a.创建指针并传递(c++)

void *FooPinter Module1::createPointer(bool p1, const std::string &p2, int p3)
{std::unique_ptr<FooPinter> pt= FooPinter::createPointer(p1, p2, p3);return pt.release(); //这里用 release() 而不是 get()
}

  b.接收并转换(c++)

const int Module1::checkPointer(void *pt)
{if (pt == NULL) {qCritical() << "传入的指针为空!";return -1;}auto pt2 = reinterpret_cast<FooPinter *>(pt); //类型转换qDebug() << pt2 ->p1() << pt2 ->p2();return 0;
}

  c.释放(c++)

const int Module1::releasePointer(void *pt)
{if (pt == NULL) {qCritical() << "传入的指针为空!";return -1;}auto pt2 = reinterpret_cast<FooPinter *>(pt); //类型转换delete pt2; //释放指针空间return 0;
}

  d.方法/参数绑定(c++, pybind11)

py::class_<Module1>(v, "Module1").def(py::init<>()).def("createPointer",&Module1::createPointer,py::arg("p1"),py::arg("p2"),py::arg("p3"),"Create the pointer.").def("checkPointer",&Module1::checkPointer,py::arg("pt"),"Check the pointer.").def("releasePointer",&Module1::releasePointer,py::arg("pt"),"Release the pointer.");

  e.调用(python)

。。。
pt = md1.createPointer(p1, p2, p3)
。。。
md1.checkPointer(pt)
。。。
md1.releasePointer(pt)

(4)字节数组处理

  a.读取并设置(python)

buff = Path('123.jpg').read_bytes()   # bytes buffer
#
imageInfo1 = md1.ImageInfo()
。。。
imageInfo1.setBytes(buff)
。。。

  b.方法/参数绑定(c++)

py::class_<ImageInfo>(v, "ImageInfo").def(py::init<>()).def("setBytes", &ImageInfo::setBytes, py::arg("bytes"), py::arg("len"), "setBytes").def("setBytes", [](ImageInfo &self, py::buffer buff) {py::buffer_info info = buff.request();const uchar *ptr = static_cast<const uchar *>(info.ptr);int len = info.size * info.itemsize;//self.setBytes(ptr, len);});

  c.接收并设置(c++)

void ImageInfo::setBytes(const uchar *bytes, int len)
{m_image = QImage::fromData(bytes, len);
}

(5)构造 QApplication 实例(c++)

。。。
namespace py = pybind11;
static std::unique_ptr<QApplication> global_qt_app;
。。。
PYBIND11_MODULE(Module1, v)
{if (!QCoreApplication::instance()) {static int fake_argc = 0;global_qt_app = std::make_unique<QApplication>(fake_argc, nullptr);}v.doc() = "Object-oriented bindings for the Module1.";
。。。

【完】

http://www.dtcms.com/a/566111.html

相关文章:

  • 新野网站建设旅行社手机网站建设方案
  • 乌兰察布市建设局网站淮安网站建设推广
  • 查看数据库表某一段时间的镜像
  • 三目运算符
  • 做兼职编辑的网站网站建设配图
  • 数组——定长滑动窗口:1343. 大小为 K 且平均值大于等于阈值的子数组数目
  • Linux如何根据一个服务端口查询是二进制还是Docker容器安装
  • Ubuntu虚拟机部署Dify+Ollama搭建智能体和工作流
  • 在百度建免费网站吗网站开发总结报告
  • 【C + +】C++11 (下) | 类新功能 + STL 变化 + 包装器全解析
  • Linux的lsblk、fdisk和gdisk
  • 企业级业务平台项目设计、架构、业务全解之平台篇
  • 玩客云做网站建设网站的网站首页
  • 淘宝客导购网站怎么做运营推广seo招聘
  • 第一次全国水利普查公报的土壤保持部分
  • 爬虫数据清洗可视化链家房源
  • 2.1.1.HTML5
  • DP1363F 多协议NFC 兼容CLRC663开发资料
  • 2025-11-03 ZYZ28-NOIP模拟赛-Round1 hetao1733837的record
  • 建设网站怎样做如何利用互联网营销
  • Claude Code 原生安装教程
  • ps做游戏下载网站有哪些做网站备案都需要什么东西
  • Anaconda Prompt系统找不到指定路径
  • 聚类(Clustering)详解:让机器自己发现数据结构
  • cglib动态代理之MethodProxy
  • 网站公网安备链接怎么做网站建设需要多少资金
  • 重点专业建设网站网上接效果图平台
  • 海北网站建设队徽logo设计
  • 北京专业网站建设网站水头网站建设
  • Git hook pre-commit