У меня есть приложение в QT 5.4, но когда мне нужно включить новую функциональность, мне нужно перекомпилировать все приложение, это займет некоторое время, мне нужно знать, как создать или изменить мое приложение, чтобы использовать созданные мной плагины.Qt5.4 Как создать приложение, основанное на плагинах?
ответ
Архитектура с плагинами требует бинарных совместимых и стабильных интерфейсов. После того, как у вас есть это, полная перекомпиляция проекта потребует столько же времени, сколько перекомпиляция одного плагина.
Скорее всего, у вас есть взаимозависимости в коде, которые в любом случае не позволяют поддерживать двоичную совместимость - если вы этого не сделали, ваши изменения будут достаточно локализованы, чтобы перекомпиляция касалась только нескольких файлов.
То, что вы пытаетесь сделать, - это решение неправильной проблемы. Исправьте структуру вашего кода, и время вашей перекомпиляции уменьшится. Нет необходимости в плагинах.
Существует много альтернатив; популярный состоит из использования разделяемых библиотек, реализующих четко определенный API.
Например. Представьте себе, что это API вы хотите открыть для настройки:
// pluggin_api.hpp
// This file defines the pluggin interface.
#pragma once
extern "C" { // avoid name mangling
const char* pluggin_name();
void foo(int x);
void bar(int y);
}
Тогда ваши пользователи (или самостоятельно) будет осуществлять различные вариации этого API, например:
// pluggin_1.cpp
#include "pluggin_api.hpp"
#include <iostream>
const char* pluggin_name() {
return "Pluggin 1";
}
void foo(int x) {
std::cout << "2 * x = " << 2 * x << std::endl;
}
void bar(int y) {
std::cout << " 3 * y = " << 3 * y << std::endl;
}
и
// pluggin_2.cpp
#include "pluggin_api.hpp"
#include <iostream>
const char* pluggin_name() {
return "Pluggin 2";
}
void foo(int x) {
std::cout << "20 * x = " << 20 * x << std::endl;
}
void bar(int y) {
std::cout << " 30 * y = " << 30 * y << std::endl;
}
Эти .cpp-файлы скомпилированы как разделяемые библиотеки; под Linux это выглядит следующим образом:
$ g++ -shared -fPIC -o pluggin_1.so pluggin_1.cpp
$ g++ -shared -fPIC -o pluggin_2.so pluggin_2.cpp
Наконец, основное приложение может вызвать различные pluggins от имени:
// main.cpp
#include <iostream>
#include <dlfcn.h> // POSIX --- will work on Linux and OS X, but
// you'll need an equivalent library for Windows
void execute_pluggin(const char* name) {
// declare the signature of each function in the pluggin -- you
// could do this in the header file instead (or another auxiliary
// file)
using pluggin_name_signature = const char*(*)();
using foo_signature = void(*)(int);
using bar_signature = void(*)(int);
// open the shared library
void* handle = dlopen(name, RTLD_LOCAL | RTLD_LAZY);
// extract the functions
auto fun_pluggin_name = reinterpret_cast<pluggin_name_signature>(dlsym(handle, "pluggin_name"));
auto fun_foo = reinterpret_cast<foo_signature>(dlsym(handle, "foo"));
auto fun_bar = reinterpret_cast<bar_signature>(dlsym(handle, "bar"));
// call them
std::cout << "Calling Pluggin: " << fun_pluggin_name() << std::endl;
fun_foo(2);
fun_bar(3);
// close the shared library
dlclose(handle);
}
int main(int argc, char *argv[]) {
for(int k = 1; k < argc; ++k) {
execute_pluggin(argv[k]);
}
}
компилировать и компоновать с dl
библиотеки:
$ g++ -o main main.cpp -std=c++14 -ldl
и (обратите внимание, что перед именем необходимо указать ./
, это связано с соглашениями об именах библиотек и маршрутами поиска):
$ ./main ./pluggin_1.so ./pluggin_2.so
Calling Pluggin: Pluggin 1
2 * x = 4
3 * y = 9
Calling Pluggin: Pluggin 2
20 * x = 40
30 * y = 90
Есть так много деталей, которые я забыл (что наиболее важно для управления ошибками). Я рекомендую вам прочитать книгу API Design for C++, чтобы найти альтернативные идеи (например, использование языка сценариев, использование наследования, использование шаблонов и их сочетание).
Мне нравится метод общей библиотеки, потому что тогда я могу использовать pluggins в других приложениях (например: я могу использовать библиотеку ctypes
Python или Matlab's loadlibrary
). Я также могу написать pluggin, скажем, в Fortran, а затем перенести его в интерфейс, совместимый с API.
И наконец: обратите внимание, что это не имеет абсолютно никакого отношения к QT (хотя QT может предоставить платформенный независимый загрузчик разделяемой библиотеки, я не знаю). Это всего лишь обычный способ, с помощью которого люди предоставляют привязки для настройки.
Документация Qt предоставляет «How To» для создания плагинов для расширения приложения на основе Qt с использованием собственных механизмов Qt. См. http://doc.qt.io/qt-5/plugins-howto.html.
Это говорит о том, что высокоуровневый API и низкоуровневый API. Вас интересует низкоуровневый API.
- 1. Основанное на базе Android приложение
- 2. Создать окно, основанное на тексте
- 3. Как работает приложение, основанное на Android?
- 4. Как упаковать приложение, основанное на реакции
- 5. Создать представление, основанное на Entity?
- 6. Как создать правило Makefile, основанное на времени?
- 7. Как создать методы (функции) в плагинах jQuery
- 8. Как создать событие, основанное на времени, на веб-сайте MVC5?
- 9. Не удалось запустить приложение, основанное на Mavericks
- 10. приложение, основанное на приложениях дополненной реальности
- 11. Опубликовать приложение, основанное на аутсорсинге - iOS
- 12. IOS запустить приложение, основанное на местоположении
- 13. Oracle создать представление, основанное на другом виде
- 14. Как настроить приложение, не основанное на war, в Tomcat?
- 15. Как развернуть приложение grails, основанное на hudson, на JbossAS 7?
- 16. Создать условное представление, основанное на атрибуте объекта?
- 17. Создать модальное окно, основанное на домене ссылки
- 18. Как защитить приложение, основанное на регистрации номера телефона?
- 19. Как создать приложение на основе окон, основанное на виду, в .NET
- 20. Поддерживает ли Qt5.4 QtWebEngine?
- 21. Qt5.4 Обновления OpenGL
- 22. навигации приложение, основанное в Xcode 4,2
- 23. Как создать подключаемое приложение Java?
- 24. Как создать переменное свойство, основанное на другом свойстве в классе
- 25. Как создать правило LinkExtractor, основанное на href в Scrapy
- 26. Cakephp, как создать виртуальное поле, основанное на другом столе
- 27. Как создать регулярное выражение, основанное на позиции и разделителе
- 28. Как создать случайное число, основанное на вероятности в r
- 29. Как создать событие, основанное на Microstrategy в базе данных Запрос?
- 30. Jenkins: Как создать представление, основанное на результатах нескольких заданий?
Вы исследовали тему? –
Скорее всего, вы используете очень медленный компилятор или машину, которая значительно недостаточна для работы, которую вы пытаетесь выполнить. –
Сколько строк кода в вашем проекте? –