如何使用CMake将静态Qt插件嵌入应用程序中?

3

我希望能够将自定义的虚拟音频设备插件嵌入应用程序中。 QAudioSystemPlugin 看起来适合这个任务。

但是它没有加载。

CMakeLists.txt

cmake_minimum_required(VERSION 2.8.11)

project(myproject)

find_package(Qt5 5.5.0 REQUIRED COMPONENTS
    Core
    Multimedia
)

set(CMAKE_AUTOMOC ON)
add_definitions("-DQT_STATICPLUGIN")

add_executable(${PROJECT_NAME}
    main.cpp
    VirtualQAudioSystemPlugin.cpp
)

target_link_libraries(${PROJECT_NAME}
    Qt5::Core
    Qt5::Multimedia
)

set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 11)

main.cpp:

#include <iostream>

#include <QCoreApplication>
#include <QAudioDeviceInfo>
#include <QtPlugin>

Q_IMPORT_PLUGIN(VirtualQAudioSystemPlugin)

int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);

    for (const auto& dev : QAudioDeviceInfo::availableDevices(QAudio::AudioInput))
        std::cerr << dev.deviceName().toStdString() << "\n";

    return app.exec();
}

VirtualQAudioSystemPlugin.hpp:

#pragma once

#include <QtMultimedia/QAudioSystemPlugin>

class VirtualQAudioSystemPlugin: public QAudioSystemPlugin
{
    Q_OBJECT
    Q_PLUGIN_METADATA(IID "org.qt-project.qt.audiosystemfactory/5.0" FILE "virtual.json")

public:
    VirtualQAudioSystemPlugin(QObject *parent = 0);
    ~VirtualQAudioSystemPlugin() {}

    virtual QList<QByteArray> availableDevices(QAudio::Mode mode) const override;
    virtual QAbstractAudioInput* createInput(const QByteArray& device) override;
    virtual QAbstractAudioOutput* createOutput(const QByteArray& device) override;
    virtual QAbstractAudioDeviceInfo* createDeviceInfo(const QByteArray& device, QAudio::Mode mode) override;
};

VirtualQAudioSystemPlugin.cpp:

#include "VirtualQAudioSystemPlugin.hpp"

#include <iostream>

VirtualQAudioSystemPlugin::VirtualQAudioSystemPlugin(QObject *parent) :
        QAudioSystemPlugin(parent)
{
    std::cerr << "VirtualQAudioSystemPlugin\n";
}

QList<QByteArray> VirtualQAudioSystemPlugin::availableDevices(QAudio::Mode mode) const
{
    std::cerr << "VirtualQAudioSystemPlugin\n";
}

QAbstractAudioInput* VirtualQAudioSystemPlugin::createInput(const QByteArray &device)
{
    std::cerr << "VirtualQAudioSystemPlugin\n";
}

QAbstractAudioOutput* VirtualQAudioSystemPlugin::createOutput(const QByteArray &device)
{
    std::cerr << "VirtualQAudioSystemPlugin\n";
}

QAbstractAudioDeviceInfo* VirtualQAudioSystemPlugin::createDeviceInfo(const QByteArray &device, QAudio::Mode mode)
{
    std::cerr << "VirtualQAudioSystemPlugin\n";
}

virtual.json:

{
    "Keys": ["default"]
}

构建和启动:未执行VirtualQAudioSystemPlugin的构造函数。

如何使其加载?

更新:我尝试将其作为动态插件,使用QT_DEBUG_PLUGINS=1显示正常,但未被创建或调用。

更新:当插件静态构建时,QT_DEBUG_PLUGINS=1未显示与插件相关的任何内容。

这是插件作为单独的库时(显示,但仍无法工作):

(请注意,我还将virtual.json中的“default”替换为“virtual”)

QFactoryLoader::QFactoryLoader() checking directory path "/usr/lib/x86_64-linux-gnu/qt5/plugins/audio" ...
QFactoryLoader::QFactoryLoader() looking at "/usr/lib/x86_64-linux-gnu/qt5/plugins/audio/libqtaudio_alsa.so"
Found metadata in lib /usr/lib/x86_64-linux-gnu/qt5/plugins/audio/libqtaudio_alsa.so, metadata=
{
    "IID": "org.qt-project.qt.audiosystemfactory/5.0",
    "MetaData": {
        "Keys": [
            "alsa"
        ]
    },
    "className": "QAlsaPlugin",
    "debug": false,
    "version": 328961
}


Got keys from plugin meta data ("alsa")
QFactoryLoader::QFactoryLoader() looking at "/usr/lib/x86_64-linux-gnu/qt5/plugins/audio/libqtmedia_pulse.so"
Found metadata in lib /usr/lib/x86_64-linux-gnu/qt5/plugins/audio/libqtmedia_pulse.so, metadata=
{
    "IID": "org.qt-project.qt.audiosystemfactory/5.0",
    "MetaData": {
        "Keys": [
            "default"
        ]
    },
    "className": "QPulseAudioPlugin",
    "debug": false,
    "version": 328961
}


Got keys from plugin meta data ("default")
QFactoryLoader::QFactoryLoader() checking directory path "/data/hd2/tmp/plugins/build/audio" ...
QFactoryLoader::QFactoryLoader() looking at "/data/hd2/tmp/plugins/build/audio/libmyproject.so"
Found metadata in lib /data/hd2/tmp/plugins/build/audio/libmyproject.so, metadata=
{
    "IID": "org.qt-project.qt.audiosystemfactory/5.0",
    "MetaData": {
        "Keys": [
            "virtual"
        ]
    },
    "className": "VirtualQAudioSystemPlugin",
    "debug": true,
    "version": 328961
}


Got keys from plugin meta data ("virtual")
loaded library "/usr/lib/x86_64-linux-gnu/qt5/plugins/audio/libqtaudio_alsa.so"
loaded library "/usr/lib/x86_64-linux-gnu/qt5/plugins/audio/libqtmedia_pulse.so"
loaded library "/data/hd2/tmp/plugins/build/audio/libmyproject.so"

"静态插件"是一个矛盾的说法。你要么链接某些东西,要么在运行时插入它。 - Nicolas Holthaus
@NicolasHolthaus,动态插件也存在同样的问题,所以我认为原因不在于静态与动态。"静态插件"是Qt术语的一部分:http://doc.qt.io/qt-5/plugins-howto.html#static-plugins - Velkan
2个回答

0

从我所见,它应该更像是这样:

class VirtualQAudioSystemPlugin : public QAudioSystemPlugin, public QAudioSystemPluginExtension
{
    Q_OBJECT
    Q_PLUGIN_METADATA(IID "org.qt-project.qt.audiosystemfactory/5.0" FILE "virtual.json")
    Q_INTERFACES(QAudioSystemPluginExtension)
etc.

你也可以将QT_DEBUG_PLUGINS环境变量设置为1,以获取更多关于正在发生的情况的信息。


为什么需要 QAudioSystemPluginExtension - Velkan
因为寻找音频系统插件的工厂将搜索实现该接口的插件。 - SGaist
SGaist,为什么它在私有头文件中,而且为什么它在5.7中不存在? - Velkan
因为这是插件实现的细节,并且这种东西在Qt版本之间可能会发生变化。从快速查看代码来看,默认设备处理已在Qt 5.8中进行了修改和改进。 - SGaist
所以它不能被使用,也没有帮助(从看起来的情况来看)? - Velkan
显示剩余4条评论

0
问题出在 virtual.json 中的 'default':它被其他插件覆盖了。如果没有其他插件,该对象将被实例化。

必须更改为类似 'virtual' 的其他内容。

{
    "Keys": ["virtual"]
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接