对 Qt dll 的 Python 支持 [英] Python support for Qt dll

查看:53
本文介绍了对 Qt dll 的 Python 支持的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有自己的用 Qt 编写的 C++ 库项目(带源代码),它使用 QTcpsocketQUdpSocketQSerialPort 信号和插槽.

I have my own C++ library project(with source) written in Qt and it uses QTcpsocket, QUdpSocket, QSerialPort signals and slots.

我也想在 Python 中支持这个库.

I would like to support this library in Python as well.

执行此操作的首选方法是什么?

What is the preferred way to do this?

  • 用 Python 编写包装器,如果是,它有障碍吗?
  • 不知道 PyQt 是否只是为了这个目的?
  • 或者您是否认为通过实现 C++ 库项目中使用的逻辑来重写 Python 中的库会更好.

由于这个库是 SDK 的一部分,同样适用于支持 QT dll 和 .NET 实际上,作为支持 Python 之后的第二步.

As this is library is part of a SDK, same applies for supporting QT dll with .NET as well in fact, as a second step after supporting Python.

Qt API 示例.

quint16 SendCommandAsync(CmdBaseSpv1* pcommand,
                         ConnectionArg connectionArg,
                         emitLogOptions::emitLogOption logOption,
                         LogInfo &txLogInfo,
                         LogInfo &rxLogInfo);

我想从 Python 调用这个函数.函数参数CmdBaseSpv1ConnectionArgemitLogOptionLogInfo都是Qt类.其中一些参数使用了 QOBJECT 基类.

I want to call this function from Python. Function parameters CmdBaseSpv1, ConnectionArg, emitLogOption, LogInfo are all Qt classes. Some of these arguments are using the QOBJECT base class.

从函数名可以看出;它是一个异步函数调用.结果会发出一个信号,所以我也需要得到异步结果.

As you see from the function name; it is an Asynchronous function call. Result will emit a signal so I need to get async result as well.

推荐答案

我会写下我所知道的关于包装 C++ 库的知识并尝试获取它,但作为一个巨大的免责声明,我我自己只将它用于非常非常简单的事情.

I'll write down what I know about wrapping C++ libraries and will try to source it, but as a huge disclaimer, I have only used this for something very, very simple myself.

您询问关于用 Python 重写库的问题.我会说这取决于.如果代码是微不足道的,那么我不明白为什么不.如果它更大并且必须与其他代码保持同步(正如你暗示的 .Net),我不会.对两者重用相同的代码是有意义的.

You ask about rewriting the library in Python. I would say this depends. If the code is trivial, then I don't see why not. If it is larger and has to be kept up-to-date with other code (as you imply with .Net), I wouldn't. It makes sense to reuse the same code for both.

从我看到的你的代码来看,我会尝试使用 boost::pythonSWIG.

From what I see of your code I would try to wrap it using boost::python or SWIG.

主要麻烦将是在 Python 中创建 CmdBaseSpv1ConnectionArg 等.

The main trouble is going to be to create CmdBaseSpv1, ConnectionArg, etc. in Python.

如果您不需要任何 Qt 类来实例化您的类,这应该很简单.但是,如果您需要 Python 内部的 Qt 类型(例如,因为 CmdBaseSpv1 的构造函数需要 QString),您的任务要复杂得多,因为您需要一种方法将 Python 字符串转换为 QString.如果可以,您应该只使用 stl-types.

If you don't need any Qt-classes to instantiate your classes, this should be straightforward. However, in case you need the Qt types inside of Python (e.g. because the constructor of CmdBaseSpv1 requires a QString), your task is a lot more complicated because you need a way to convert a Python-string into a QString. If you can, you should only use stl-types.

包装小型 C 库的最简单方法是使用 cffi 模块(或ctypes).您可以在 Python 中编写完整的绑定.但是,如果您的 API 很大并且可能会变得困难,那么这需要大量的手动工作.

The simplest way to wrap a small C library is to use the cffi module (or ctypes). You can write the full binding in Python. However, this is a lot of manual work if your API is large and can get difficult.

还有一个问题:ctypes 仅与 C 兼容,不是 C++.所以你需要改变你的界面以兼容 C,在内部你仍然可以使用 C++ 和 Qt.

There is another problem: ctypes is only compatible with C, not C++. So you'd need to change your interface to be compatible with C, internally you could still use C++ and Qt.

另一种方法是自己包装库调用.您可以使用 Python API 来执行此操作.还有一些库可以帮助您创建绑定.Boost::python 似乎特别很有前途并使用 C++.

An alternative is to wrap the library calls yourself. You can either do this by using the Python API. There are also a few libraries that help you create the bindings. Boost::python seems especially promising and works with C++.

如果您的 API 非常大,您应该使用绑定生成器来解析 C++ 代码并生成绑定本身.例如 sip 就是其中之一.它用于为整个 Qt 库创建绑定.有一些绑定生成器,Python 文档中提到的一个是 SWIG.PySide 使用 Shiboken,并且在他们的网站上也有很好的描述.

If your API is very large, you should use a binding generator which parses the C++ code and generates the bindings itself. For example sip is one of them. It is used to create the bindings for the whole Qt library. There are a few binding generators out there, one mentioned in the Python docs is SWIG. PySide uses Shiboken and also has a nice description of it on their website.

SWIG 具有额外的优势,您可以为多种语言(包括 C#)创建绑定.

SWIG has the additional advantage, that you can create bindings for multiple languages, including C#.

PyQt 是使用 sip 从 Qt 生成的绑定.您可能不需要它,除非您需要从 Python 内部访问 Qt 的全部功能.如果是这种情况,请考虑使用 sip 来生成绑定,这样信号槽机制之类的东西就可以在您的库和 PyQt 之间兼容.

PyQt is a binding generated from Qt using sip. You'll probably not need it, unless you need to access the full power of Qt from inside Python. If this is the case, consider using sipfor generating the bindings, so things like the signal-slot mechanism are compatible between your library and PyQt.

绑定会带来一些挑战,因为 Python 和 C++ 在某些关键领域有所不同.

Bindings come with a few challenges because Python and C++ are different in some key areas.

Python 中的内存管理几乎是自动的,而在 C++ 中,您需要手动进行.例如

Memory management in Python is almost automatic, in C++ you're required to do it manually. For example

def myfunc():
    mywidget = QWidget()

myfunc() 的末尾,mywidget 被垃圾收集.然而在 C++ 中

at the end of myfunc() mywidget gets garbage collected. In C++ however

void myfunc() {
    auto mywidget = new QWidget();
}

mywidget 仍然存在.这意味着即使在 Python 中,您也需要处理 C++ 内存管理.我见过的问题是内存泄漏和悬空指针.使用回调时要注意这一点,你不希望 Python 在 C++ 认为它仍然存在时垃圾收集回调.

mywidget is still around. This means that even when inside Python, you need to take care of the C++ memory management. The problems I've seen are memory leaks and dangling pointers. Watch out for this when using callbacks, you don't want Python to garbage collect the callback while C++ thinks it's still alive.

并非所有的编程语言都有例外或以相同的方式处理它们.例如,如果可以在 Python 中捕获 C++ 中的异常,那就太好了.

Not all programming languages have exceptions or deal with them the same way. For example, it would be nice if an exception inside C++ can be caught inside Python.

  • How to wrap a c++ library for python? (example of boost::python)
  • Exposing a C++ API to Python (discussion about boost::python, SWIG and more)
  • https://stackoverflow.com/a/5686873 (discusses Cython, another choice)

这篇关于对 Qt dll 的 Python 支持的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆