Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: Как правильно собрать приложение Qt с динамической библиотекой?

Доброго времени суток.
Есть собранная статически библиотека. Исходники, .a-файл тоже имеются. Теперь нужно используя эту библиотеку написать приложение так, чтобы оно не тянуло с собой весь фреймворк Qt, а использовало то, что есть в библиотеке. Статически линковать приложение нельзя, потому что получается что библиотека весит 18Мб и приложение ровно столько же, хотелось бы разделить функционал библиотеки и функционал приложения.

Я попробовал собрать приложение компилятором Qt из коробки с подключенной библиотекой, но при запуске приложение сразу пытается найти Qt5Core.dll

Так же пробовал создать "Проект без использования Qt", но тогда он, естественно, не находит инклуды Qt-шных хедэров из библиотеки.

Попробовал подправить в этом проекте .pro-файл:
Код C++ (QT)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
TEMPLATE = app
#CONFIG += console
#CONFIG -= app_bundle
#CONFIG -= qt
 
QT += core widgets gui
SOURCES += main.cpp
 
include(deployment.pri)
qtcAddDeployment()
 
INCLUDEPATH += C:/Qt/pro/my_qt_dll
 
LIBS += C:/Qt/pro/my_qt_lib/dev/libmy_qt_dll.a
но при попытке собрать это дело вываливаются ошибки вида:
Код C++ (QT)
1
2
main.cpp:-1: ошибка: undefined reference to `qt_static_plugin_QWindowsIntegrationPlugin()'
main.cpp:-1: ошибка: undefined reference to `qt_static_plugin_QDDSPlugin()'
Как правильно все это дело организовать? Может нужно в библиотеке что-то исправить?

Qt 5.5.0 (MinGW), Windows

Добавлено через 7 часов 3 минуты
Разобрался. Оказывается всё решается в два щелчка: в исходники библиотеки нужно было добавить __declspec(dllexport) перед расшаренными функциями/классами.

Чтобы избавить от последней ошибки, связанной с плагинами, добавил в библиотеку перед испортом плагинов проверку:
Код C++ (QT)
1
2
3
4
5
6
7
8
9
10
11
12
#ifndef NO_IMPORT_QT_PLUGINS
#include <QtPlugin>
Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin)
Q_IMPORT_PLUGIN(QDDSPlugin)
Q_IMPORT_PLUGIN(QICNSPlugin)
Q_IMPORT_PLUGIN(QICOPlugin)
Q_IMPORT_PLUGIN(QJp2Plugin)
Q_IMPORT_PLUGIN(QMngPlugin)
Q_IMPORT_PLUGIN(QTgaPlugin)
Q_IMPORT_PLUGIN(QTiffPlugin)
Q_IMPORT_PLUGIN(QWbmpPlugin)
#endif
.pro файл приложения:
Код C++ (QT)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
TEMPLATE = app
CONFIG -= app_bundle
CONFIG -= qt
 
SOURCES += main.cpp
 
include(deployment.pri)
qtcAddDeployment()
 
# Заголовочные файлы библиотеки
INCLUDEPATH += C:/src/my_qt_lib
 
# Заголовочные файлы Qt
INCLUDEPATH += C:/Qt/5.5.0_Static/include\
    C:/Qt/5.5.0_Static/include/QtWidgets\
    C:/Qt/5.5.0_Static/include/QtCore\
    C:/Qt/5.5.0_Static/include/QtGui
 
# Определяем 
DEFINES += NO_IMPORT_QT_PLUGINS
 
# Библиотека импорта (.a или .lib)
LIBS += C:/src/my_qt_lib/dev/libmy_qt_dll.a
Ответ: WxMaper, я не юрист, это нужно на форуме Qt спрашивать. Но суть в том что вы лицензию покупаете на Qt для личного использования, а вы по сути предоставляете Qt как часть своего продукта.
То есть вы покупаете право использовать Qt в коммерческих целях, а не распространять его.
Вопрос: Сборка динамической библиотеки

Пытаюсь собрать динамическую библиотеку для использования её из питона.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <string>
#include <sys/ptrace.h>
#include <errno.h>
#include <cstdlib>
 
using namespace std;
 
int main(int argc, char* argv[])
{
pid_t pid = atoi(argv[1]);
//~ int addr = atoi(argv[2]);
int addr = 0x00329304;
int ret = ptrace(PTRACE_ATTACH, pid, NULL, NULL);
cout << "ptrace Status: " << ret << endl;
cout << "Errno: " << errno << endl;
ret = ptrace(PTRACE_PEEKDATA, pid, addr, NULL);
cout << "ptrace Status: " << ret << endl;
cout << "Errno: " << errno << endl;
int _ret = ptrace(PTRACE_DETACH, pid, NULL, NULL);
cout << "ptrace Status: " << _ret << endl;
cout << "Errno: " << errno << endl;
return ret;
}
опции сборки
C++
1
2
g++ -fPIC -c ptrace6.cpp
g++ -shared -o output.so ptrace6.o
При запуске собранной библиотеки получаю ошибку сегментирования
Если же собирать исполняемый файл с помощью
C++
1
g++ -lm -o output ptrace6.cpp
все работает как положено.
Что я делаю не так? И как делать правильно?
Ответ:
Сообщение от ampermetr
И как делать правильно?
Динамическая библиотека собирается так:

Код
$ g++ -fPIC t1.cpp -o t1.o
$ g++ -fPIC t2.cpp -o t2.o
$ g++ -fPIC t3.cpp -o t3.o
$ g++ -shared t1.o t2.o t3.o -o libtrampampam.so
ну или всё это же самое в одну строку

Код
$ g++ -fPIC -shared t1.cpp t2.cpp t3.cpp -o libtrampampam.so
Вопрос: Подключение динамической библиотеки с другого каталога

Всем привет. Тема знаю что не новая, везле есть подобные вопросы и ответы. Но правда может плохо искал.
В проект подключается динамическая библиотека. Выглядит так. Заранее благодарю за помощь.
/MyProject
|--subdir
| |-Mylib.cpp
| |-Mylib.hpp
| |-Mylib.pro
|
|-CMainWindow.cpp
|-CMainWindow.hpp
|-main.cpp
|-CMainWindow.pro

Вопрос такой, как правильно прописать в конфиге проекта чтобы он увидел файлы кода библиотеки и при сборке создавал каталог куда будет запихивать библиотеку и туда проект будет и ссылаться? Ниже привожу конфиг
Код C++ (QT)
1
2
3
4
5
6
7
8
9
10
11
12
QT += widgets
 
TARGET = testProject
TEMPLATE = app
 
LIBS += subdir/libmylib.so
 
 
SOURCES += main.cpp\
        CMainWindow.cpp
 
HEADERS  += CMainWindow.hpp
Ну и конфиг библиотеки есть это важно.
Код C++ (QT)
1
2
3
4
5
6
7
8
9
10
QT       -= gui
 
TARGET = Mylib
TEMPLATE = lib
 
DEFINES += LIB_LIBRARY
 
SOURCES += Mylib.cpp
 
HEADERS += Mylib.hpp\
Ответ: BlinCT, что значит не видит? Либа там вообще лежит? Вы ее уже собрали?
Вопрос: Отладка динамической библиотеки

Скомпилировал я динамическую библиотеку, присоединил к проекту. Папка с исходниками библиотеки лежит в отдельной папке (не в папке проекта, проект ничего не знает про эту папку). Делаю пошаговую отладку кнопкой F11. Нарываюсь на библиотечную функцию и меня перекидывает на определение этой функции и отладка уже идет по ней.
То есть каким то образом нашлись исходники библиотеки. Как такое может быть?
Возможно из-за того что я открывал до этого эти файлы.
Ответ: Рискну предположить, что присоединенная библиотека была собрана в debug режиме. Попробуй снова открыть проект библиотеки, переключить режим сборки на Релиз и собрать ее. Затем уже к своему основному проекту пихнуть релизные файлы собранной либы.
Вопрос: Как подключить к приложению AnyCPU библиотеку x86?

Дано:
1. Есть приложение на C#, собранное под AnyCPU, оно подсасывает библиотеки из определенной папки.
2. Одна из библиотек устарела, в ней нужно использовать функции, описанные в библиотеке на c++, которая собрана как x86.
3. Основное приложение и библиотеку на плюсах переписывать нельзя.
4. Плюсовая библиотека подключается через DLLImport.
5. Винда x64, но в дальнейшей эксплуатации может быть любая

Что пробовал (неудачные попытки):
1. Изменить разрядность библиотеки на c# на x86. Результат: не подключается к программе. Если просто проект новый AnyCPU создать и в ссылках подключить эту библиотеку, то тоже ошибку выдает.
2. Не менять нигде разрядность. Результат: ошибка о невозможности подключить один или несколько модулей, связанных с библиотекой на плюсах.
3. Создать библиотеку на плюсах, скомпилировать под x64, а из нее вызывать x86. Результат: как и в прошлом способе.

Вопрос: как быть-то тут? Как плюсовую библиотеку x86 подключить к шарповскому проекту AnyCPU? Допускаются любые костыли и говнокод, главное чтоб работало.
Ответ:
Сообщение от nicolas2008
Надо пропатчить только запускаемый exe файл
пересобрал под x86, не помогло

Сообщение от kolorotur
создайте управляемую обертку для сишной либы, зарегистрируйте ее в COM
Обертка на шарпе стало недоCOM-объектом, который в .NET не подключается, а на плюсах чет пошло не так. Собственно, на плюсах была и еще одна библиотека, с тем же функционалом примерно, и работающая как COM-объект, но в итоге и с ней плохо. Она собрана win32, а шарп все равно требует x64. Пересобрал под x64, но не смог зарегистрировать. Проклинаю всю винду...
Вопрос: Создать динамическую библиотеку, вызывающую функцию из статической

Доброго времени суток!
тут появилось два вопроса:
1)создать динамическую библиотеку, вызывающую функцию из статической
2)статическую библиотеку, вызывающую функцию из динамической

Пусть мы пока смотрим на первый вопрос, помогите мне найти ошибку, или подскажите как можно сделать по другому:
я создаю статическую библиотеку:
для этого пишу код:
C
1
2
3
4
5
6
7
#include <stdio.h>
 
extern int sort()
{
 printf("\nHello World!\n");
 return 0;
}
Назову программу aStatic.c
теперь создаю саму библиотеку, пишу для этого в терминале:
gcc -c ./aStatic.c -o aStatic.o
ar rc aStatic.a aStatic.o
ranlib aStatic.a
На этом этапе нигде ошибок не выдает

далее создаю динамическую библиотеку:
C
1
2
3
4
5
6
7
#include <stdio.h>
extern int sort();
extern int mainDS()
{
    sort();
    return 0;
}
Назову файл aDS.c
теперь создаю сам файл библиотеки в консоли со статической загрузкой:
gcc fPIC -c ./aDS.c -o aDS.o
gcc -shared -o aDS.so aDS.o
Тут пока тоже без ошибок
далее пишу программу, в которой использую динамическую библиотеку:
C
1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
extern int mainDS();
 
int main()
{
    printf("Dynamic library with static loader");
    int x = mainDS();
    printf("Return code: %d\n",x);
    return 0;
}
назову программу eProg.c
и компилирую её вместе с динамической и статической библиотекой:
gcc ./eProg.c aDS.so aStatic.a
Ошибок по прежнему нет
теперь запускаю файл запуска:
./a.out
и тут мне пишет:
./a.out: error while loading shared libraries: aDS.so: cannot open shared object file: No such file or directory
когда делаю аналогичные действия для обратной задачи - такая же ошибка, помогите разобраться, я считаю, что мне нужно как-то при сборке динамической библиотеке указать файл статической библиотеки, но как это сделать я не придумал
Спасибо заранее
Ответ:
Сообщение от Cra3y
Текущая директория находится вне списка, где система ищет библиотеки
Нужно запускать программу с установкой переменной окружения LD_LIBRARY_PATH

Да, прописал это в терминале, и указал вместо ./prog_name ./a.out и всё заработало
Большое спасибо!

Добавлено через 4 часа 28 минут
Знаю, что не в этот раздел, но что делать, если такая же ситуация возникает в OS Windows, пишет:
>main.obj : error LNK2019: ссылка на неразрешенный внешний символ __imp__sortT в функции _main
1>F:\andro\C++\os\Lab8\eProg\Debug\eProg.exe : fatal error LNK1120: неразрешенных внешних элементов: 1

Добавлено через 21 минуту
всё заработало, просто забыл при создании второй библиотеки подключить заголовочные файлы обоих библиотек
Вопрос: Qt динамические библиотеки

Здравствуйте, в Шлее почитал, что можно подключить динамическую библиотеку. Создаю я ее образом: новый проект -> Библиотеки -> Библиотека C++ . Дополнив мою библиотеку одним методом получаю такие файлы:
Заголовочный "plug2.h"
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#ifndef PLUG2_H
#define PLUG2_H
 
#include "plug2_global.h"
 
class PLUG2SHARED_EXPORT Plug2
{
 
public:
    Plug2();
    double fun(int,int);
};
 
#endif // PLUG2_H
Заголовочный "plug2_global.h"
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
#ifndef PLUG2_GLOBAL_H
#define PLUG2_GLOBAL_H
 
#include <QtCore/qglobal.h>
 
#if defined(PLUG2_LIBRARY)
#  define PLUG2SHARED_EXPORT Q_DECL_EXPORT
#else
#  define PLUG2SHARED_EXPORT Q_DECL_IMPORT
#endif
 
#endif // PLUG2_GLOBAL_H
Файл "plag2.cpp"
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
#include "plug2.h"
 
Plug2::Plug2()
{
}
 
double Plug2::fun(int a, int s)
{
    return a + s;
}
Ну иpro файл
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
QT       -= gui
 
TARGET = plug2
TEMPLATE = lib
 
DEFINES += PLUG2_LIBRARY
 
SOURCES += plug2.cpp
 
HEADERS += plug2.h\
        plug2_global.h
 
unix {
    target.path = /usr/lib
    INSTALLS += target
}
Собираю я проект выставляя в сборке Отладка. Получая папку build с папкой debug, где лежит файл plug2.dll.

Далее создаю новый проект: Обычный С++. Как я понял из Шлее:
в pro-файл нужно включить ее
вместе с путем ее размещения, а также и путь ее заголовочных файлов. Например:
LIBS += -L../../lib/ —ITools
INCLUDEPATH = ../../include

В своем pro файле я выставляю:
C++ (Qt)
1
2
3
4
5
6
7
8
9
TEMPLATE = app
CONFIG += console c++11
CONFIG -= app_bundle
CONFIG -= qt
 
SOURCES += main.cpp
 
LIBS += -L "E:\QT\build-plug2-Desktop_Qt_5_7_0_MinGW_32bit-Debug\debug" -lplug2
INCLUDEPATH = E:\QT\plug2
и сам мой файл main.cpp
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include <plug2.h>
#include <plug2_global.h>
 
 
using namespace std;
 
int main(int argc, char *argv[])
{
    Plug2 pl;
    cout << pl.fun(1,2) << endl;
    return 0;
}
На что мне выдает ошибку (скрин ниже), в чем проблема?
Ответ:
Сообщение от UltraPenguin
Проект "Обычного С++" ничего не знает про Qt и его заголовочные файлы.
Создайте вместо этого например Qt Console Application или Qt Widgets Application и будет вам счастье.
Спасибо, только теперь почему-то когда я создаю объект моего класса программа прекращается (не выводится в консоль сообщение, просто открывается консоль и ждет нажатие клавиши enter) вот код:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <QCoreApplication>
#include <plug2.h>
#include <QDebug>
#include <plug2_global.h>
 
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    Plug2 *pl = new Plug2;
 
    double s = pl->fun(1,3);
 
    qDebug() << "daskl";
 
    delete pl;
 
    return a.exec();
}
Добавлено через 14 минут
Решил проблему добавив библиотеку через нажатие правой кнопки мыши по проекту и выбрав пункт "Добавить Библиотеку"
Вопрос: Как правильно собрать ICU для g++ под Windows?

Не получается собрать ICU для компилятора g++ 4.8.2. Делаю через MSYS.
Мои команды:
cd D:/Temp/icu/source
./runConfigureICU MinGW --prefix=D:/Temp/dist --enable-static --disable-shared
Всегда получаю одно и тоже самое:
configure: error: cannot run C compiled programs
Как правильно собрать?
Делал по этому туториалу:
Ответ:
Сообщение от DiffEreD
В двух словах на будущее, что за проблема с этими файлами была?
Файлы, которые шли в комплекте с ISU, просто "не в курсе" были что это за платформа такая MSYS2.
Ты скачал последнюю версию, в которой, в числе прочих, есть сведения о том, как правильно конфигурировать для MSYS2.

Кстати, именно об этом написано в логе, который ты прикрепил и даже ссылки даны те же самые
This script, last modified 2013-11-29, has failed to recognize
the operating system you are using. It is advised that you
download the most up to date version of the config scripts from


and
Вопрос: MSVC2012: Сборка динамических библиотек и погода на Венере

Всем здравствуйте, у меня опять бяда:
Есть приличный прожект, в котором приложение разбито на динамические модули. Все они - подпроекты, библиотеки, большая половина которых подключается динамически (QPlugin), а меньшая - прилинковывается (LIBS += -L) (см. Qt Creator). И всё в нём хорошо, да только вот сборка даёт сбои.
Конкретнее, msvc2012 не собирает одну из линкуемых библиотек. Точнее, собирает, но не всю. Для одной из библиотек не строится .lib файл, без которого, в общем, толку от dll нет. Ну и ещё .exp не строится.

Все собираются достаточно просто

Вот это взлетает
Код Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#-------------------------------------------------
#
# Project created by QtCreator 
#
#-------------------------------------------------
DEFINES += ACTIVEX_LIBRARY
QT       += axcontainer
 
TARGET = ActiveX
TEMPLATE = lib
CONFIG += shared dll
 
win32-g++:CONFIG(release, debug|release): DESTDIR = $$PWD/../../../bin/gccrelease/Libs/
else:win32-g++:CONFIG(debug, debug|release): DESTDIR = $$PWD/../../../bin/gccdebug/Libs/
else:win32-msvc2012:CONFIG(release, debug|release): DESTDIR = $$PWD/../../../bin/msvc2012release/Libs/
else:win32-msvc2012:CONFIG(debug, debug|release): DESTDIR = $$PWD/../../../bin/msvc2012debug/Libs/
 
SOURCES += \
    ActiveX.cpp
HEADERS += \
    ActiveX.h \
    ActiveX_global.h
unix {
    target.path = /usr/lib
    INSTALLS += target
}
INCLUDEPATH += E:\Projects\Application\include
Вот это не взлетает
Код Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#-------------------------------------------------
#
# Project created by QtCreator
#
#-------------------------------------------------
DEFINES += PLUGININTERFACE_LIBRARY
QT       += widgets
 
TARGET = PluginInterface
TEMPLATE = lib
CONFIG += shared dll
 
win32-g++:CONFIG(release, debug|release): DESTDIR = $$PWD/../../../bin/gccrelease/Libs/
else:win32-g++:CONFIG(debug, debug|release): DESTDIR = $$PWD/../../../bin/gccdebug/Libs/
else:win32-msvc2012:CONFIG(release, debug|release): DESTDIR = $$PWD/../../../bin/msvc2012release/Libs/
else:win32-msvc2012:CONFIG(debug, debug|release): DESTDIR = $$PWD/../../../bin/msvc2012debug/Libs/
 
SOURCES += \
    iPlugin.cpp \
    lpPluginManager.cpp \
    lpPluginSpecification.cpp
 
HEADERS += \
    lpPluginManager.h \
    lpPluginManager_p.h \
    lpPluginSpecification.h \
    lpPluginSpecification_p.h \
    iPlugin_p.h \
    iPlugin.h \
    lpplugininterface_global.h
unix {
    target.path = /usr/lib
    INSTALLS += target
}
 
INCLUDEPATH += E:\Projects\Application\include

Проблем с кодом нет, DLL рабочие, это я сразу проверил. GCC делает всё правильно. Что делать, ума не приложу.

Не по теме:

А если кто спросит, зачем мне msvc сборка, я ему не отвечу.

Ответ:
Сообщение от Avazart
Говорите технически точно
Для динамической библиотеки не генерируется файла статической библиотеки, необходимого для динамической компановки.

Добавлено через 25 минут
Ок, очепятался в дефайне в lpplugininterface_global.h
Вопрос: Создание динамической библиотеки для GUI

Доброй ночи, дорогие форумчане!
Пишу Вам впервые, работаю с QT всего-ничего, так что не серчайте.
Итак, есть некий проект, в котором происходит обработка комплексных чисел. Захотелось к этому проекту прекрутить графику. Сделал проект динамической библиотеки в QT, в котором описал форму (проект в QT будет просто отображает полученные из главного файла комплексные данные в виде точки на комплексной прямой), в главном проекте создал класс, инкапсулирующий в себя владение функциями данной библиотеки.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//main.cpp
int main(int const argc, char const* const * argv) 
{
   gui qt_gui;
  //реализация объекта класса, конструктор которого загружает динамическую библиотеку
  //и запускает метод run_gui(), который описан в проекте Qt и служит для запуска GUI
   while(qt_gui.is_next)
   {
     // далее идет код обработки различных комплексных чисел
 
      qt_gui.put_sample(std::complex<double> data);
     //метод, который передает в GUI комплексное число, GUI  выводит его на экран
   }
   //код далее...
}
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//interface.cpp в проекте QT
#include "interface.h"
 
#include "mainwindow.h"
#include <QApplication>
 
 
void
run_gui(void)
{
    int a = 0;
    char **av = NULL;
    
    QApplication app(a,av);
    
    MainWindow main_window();
    
    main_window.show();
 
    app.exec();
 
}
При запуске конструктора объекта класса gui запускается функция run_gui и ,соответственно, цикл обработки событий app.exec(). На этом ход программы останавливается и дальнейший код в main.cpp не выполняется.
Вопрос состоит в следующем: как правильно организовать подобное взаимодействие? Стоит понимать, что комплексная точка будет не одна, проект будет работать в бесконечном цикле до нажатия стоп-кнопки либо закрытия приложения, а на экран будут выводится N-ое количество этих точек.
P.s. И доп вопрос: что лучше использовать для построения точек на графике?
P.s.s. Заранее благодарен
Ответ: LeviSkay, Qt Gui основан на QEventLoop, который представляет из себя бесконечный цикл. В app.exec() автоматом запускается QEventLoop.
Выводи все вычисления в отдельный QThread-поток. И уже из потока обращайся с помощью системы соединений к соответствующим слотам элементов GUI-потока.



Добавлено через 1 минуту
Для вывода графиков можно использовать QtCharts или QCustomPlot.