Russian Qt Forum
Ноябрь 23, 2024, 23:00 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Как максимально оптимизировать размер EXE при статической линковке  (Прочитано 9465 раз)
G-virus
Гость
« : Февраль 06, 2010, 00:35 »

Всем привет. Как можно уменьшить размер EXE при статической линковке. Так получилось, что приходится собирать статически свои приложения для друзей. Да и при сборке возникает куча проблем с динамикой. Тут возник вопрос. Почти любой проект поулучается в районе 7,5 Мб + сжимаю UPX'ом = 2,5 Мб. Создал простой сервер, принимающий сообщения. Как можно не использовать в нем QMainWindow( QWidget, QDialog)? Если просто тупо не использую, приложение не "тормозит" как стандартное gui, а вырубается( или даже не вырубается). в итоге Сервер не запускается. Помогите плиз!

Точнее он запускается, принимает 1 сообщение и программа завершает работу
« Последнее редактирование: Февраль 06, 2010, 00:45 от G-virus » Записан
kibsoft
Хакер
*****
Offline Offline

Сообщений: 625


Просмотр профиля WWW
« Ответ #1 : Февраль 07, 2010, 15:15 »

Если я правильно понял, и GUI тебе не нужен, то вместо QApplication используй QCoreApplication, тогда меньше будет весить exe..
Записан

http://kibsoft.ru - Download the Qt Media Encoding Library here

The apps that were written using QtMEL:
http://srecorder.com - Screen recording software
kibsoft
Хакер
*****
Offline Offline

Сообщений: 625


Просмотр профиля WWW
« Ответ #2 : Февраль 07, 2010, 19:58 »

А еще более параноидальный способ получить малый exe - это взять исходники нужных классов с Qt и всунуть их в проект))
Незнаю будет ли это работать, т.к. еще возможно будут требоваться другие классы, нужные для работы Qt приложения.
Записан

http://kibsoft.ru - Download the Qt Media Encoding Library here

The apps that were written using QtMEL:
http://srecorder.com - Screen recording software
G-virus
Гость
« Ответ #3 : Февраль 08, 2010, 15:21 »

А еще более параноидальный способ получить малый exe - это взять исходники нужных классов с Qt и всунуть их в проект))
Незнаю будет ли это работать, т.к. еще возможно будут требоваться другие классы, нужные для работы Qt приложения.

Так они же вроде тянут функции еще с других библ, как мне кажется =)

Если я правильно понял, и GUI тебе не нужен, то вместо QApplication используй QCoreApplication, тогда меньше будет весить exe..
Вы правильно поняли, но фишка в том, что когда использую QtCoreApplication, программа срабатывает как консольная (без "тормоза") То есть запускается сервер, прослушка порта, как только получит любой входящий пакет, код выполняется дальше и программа завершается. Как бы объяснить, вот если gui-программу запустить, то она работает пока мы ее не завершим, а консолька моментально срабатывает и выключается.

Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #4 : Февраль 08, 2010, 15:30 »

Поищите на этом форуме решение + поищите на crossplatform.ru

Уже обсуждалось это.

Вот для этого форума пост: http://www.prog.org.ru/topic_11251_0.html
смотрите там (тык) в ответе №3 Улыбающийся
вот этот (тык) приведет вас на кроссплатформ.ру и там смотрите сообщение №38
« Последнее редактирование: Февраль 08, 2010, 15:35 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
kibsoft
Хакер
*****
Offline Offline

Сообщений: 625


Просмотр профиля WWW
« Ответ #5 : Февраль 08, 2010, 17:53 »

Цитировать
Так они же вроде тянут функции еще с других библ, как мне кажется =)
Ой, я прогнал...забыл про наследование)) тогда это отпадает..

Вот нарыл в документации(метод exec()):
Цитировать
To make your application perform idle processing (i.e. executing a special function whenever there are no pending events), use a QTimer with 0 timeout. More advanced idle processing schemes can be achieved using processEvents().
Записан

http://kibsoft.ru - Download the Qt Media Encoding Library here

The apps that were written using QtMEL:
http://srecorder.com - Screen recording software
G-virus
Гость
« Ответ #6 : Февраль 08, 2010, 21:03 »

Вот нарыл в документации(метод exec()):

а вот этот QTimer с 0 таймаутом как использовать? или второй способ. Можете фрагмент кода прислать? Улыбающийся
Записан
kibsoft
Хакер
*****
Offline Offline

Сообщений: 625


Просмотр профиля WWW
« Ответ #7 : Февраль 08, 2010, 23:19 »

А код большой у тебя? Может выложишь, а то не видя код думать... Хотя бы опиши что и куда отсылается..
Записан

http://kibsoft.ru - Download the Qt Media Encoding Library here

The apps that were written using QtMEL:
http://srecorder.com - Screen recording software
G-virus
Гость
« Ответ #8 : Февраль 09, 2010, 00:26 »

А код большой у тебя? Может выложишь, а то не видя код думать... Хотя бы опиши что и куда отсылается..

Короче смотри. Вот код main.cpp
Код
C++ (Qt)
#include "mainwindow.h"
#include <QTextCodec>
#include <QApplication>
//#include <QMainWindow>
int main(int argc, char *argv[])
{
QTextCodec * myTextCodec = QTextCodec::codecForName("cp1251");
QTextCodec::setCodecForLocale( myTextCodec );
QTextCodec::setCodecForTr( myTextCodec );
QTextCodec::setCodecForCStrings( myTextCodec );
   QApplication a(argc, argv);
   QMainWindow *w = new QMainWindow;
   w->setGeometry(0,0,0,0);
   TripServer server;                          
   if( !server.listen( QHostAddress::Any, 6178 ) )        // Запуск сервера
       return 1;
w.show();                                              // если убрать строку, то программа принимает тоьлко 1 сообщение
   return a.exec();
}
 

То есть readClient() выполняется один раз. А если w.show() оставлять, то все работает отлично, но программа много весить начинает из-за QMainWindow
Записан
BRE
Гость
« Ответ #9 : Февраль 09, 2010, 07:28 »

Ты консольную программу хочешь сделать?
Тогда вместо QApplication используй QCoreApplication и в .pro файле укажи QT -= gui.
Записан
G-virus
Гость
« Ответ #10 : Февраль 09, 2010, 16:18 »

Ты консольную программу хочешь сделать?
Тогда вместо QApplication используй QCoreApplication и в .pro файле укажи QT -= gui.

Нет, я хочу сделать не консольную программу, но в ней не должно быть формы вообще. То есть все методы и функции (QMessageBox, QInputDialog например) должны работать (как в простом gui), но формы и классов QMainWindow, QWidget или QDialog не должно быть. Возможно ли так? И чтобы как я писал ранее, программа "становилась в режим ожидания" а не выполнялась линейно как консольная. Возможно я хреново объяснил.... Улыбающийся
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #11 : Февраль 09, 2010, 16:48 »

Ну так в чем проблема?
Код:
...
    MyClass myclass; // реализуеш у себя где-то в *.h и *.cpp класс унаследованный от QObject в котором есть слот, который что-то там будет делать.

    TripServer server;    
    connect(&server, SIGNAL(newConnection()), &myclass, SLOT(mySlot()));                    
    if( !server.listen( QHostAddress::Any, 6178 ) )        // Запуск сервера
        return 1;

    return a.exec();
...

или в чем проблема?
« Последнее редактирование: Февраль 09, 2010, 16:50 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
G-virus
Гость
« Ответ #12 : Февраль 09, 2010, 20:14 »

Видимо меня не поняли и плохо объяснил. Объясняю еще раз. У меня имеется серверное приложение без формы. Там используется два класса, наследуемых от QTcpSocket и QTcpServer. Взял gui, потому что хочу использовать такие функции как QMessageBox месаги, keyPressEvent и т.п. Фишка в том, что даже при отсутствии формы, программа работает как gui (то есть выполняется весь код в main.cpp, а потом прога встает как бы в ожидание команд) Так происходит, если создать объект классов QMainWindow, QWidget или QDialog и потом вписать метод w->show();. Если же этого не делать( не вставлять метод w->show()) то программа выполняет код в main.cpp и вырубается. А так как там стоит команда открытия порта 6178, программа прослушивает этот порт до появления первого входящего пакета. После получения пакета, программа завершается (то есть отсутствует  объекты классов QMainWindow, QWidget или QDialog и функция w->show() и компилятор опозанает ее как консольную). Мой вопрос в том, как заставить работать прогу только без классов QMainWindow, QWidget или QDialog (много весят) и без формы, но чтобы она так же могла переходить в режим ожидания команд как любая другая Gui прога. Уже не знаю как объяснять))))
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #13 : Февраль 09, 2010, 20:28 »

Я тебе выше предложил вариант. Чем не устраивает? Где она завершается? И причем тут вообще формы, диалоги, виджеты?  Учи матчасть Улыбающийся

Можешь вообще сделать так (для примера):

myclass.h
Код:
class MyClass: public QObject
{
    Q_OBJECT
public:
    MyClass::Myclass(QObject *parent = 0)
        : QObject(parent) {

        server = new QTCPServer(this);
        connect(server, SIGNAL(newConnection()), this, SLOT(mySlot()));
        if (!server->listen(QHostAddress::Any, 6178)) {
            qDebug() << "Listen is failure";
            return;
        }
    }
private slots:
    void mySlot() {
    // тут твоя реализация по обработке входящих соединений и т.п.
    }
private:
    QTCPServer *server;
}

main.cpp
Код:
int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);

    MyClass myclass;

    return app.exec();
}

« Последнее редактирование: Февраль 09, 2010, 20:40 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
G-virus
Гость
« Ответ #14 : Февраль 09, 2010, 21:31 »

Воспользовавшись вашим советом, у меня существенно убавился объем EXE, но, сервер не реагирует на входящие сообщения (раньше реагировал). вот код .h файла:
Код
C++ (Qt)
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
 
#include <QTcpServer>
#include <QTcpSocket>
 
class ClientSocket : public QTcpSocket
{
   Q_OBJECT
public:
   ClientSocket(QObject *parent = 0);
       int id;
 QString strA, strB;
private slots:
   void readClient();
};
class TripServer : public QObject
{
   Q_OBJECT
public:
   TripServer( QObject *parent = 0 ) : QObject( parent ) {
                                                        server = new QTcpServer(this);
                                                         connect(server, SIGNAL(newConnection()), this, SLOT(mySlot()));
                                                   server->listen(QHostAddress::Any, 6178);
                                                         }
private:
   QTcpServer *server;
private slots:
   void mySlot(int socketID){
       ClientSocket *socket = new ClientSocket( this );
       socket->setSocketDescriptor( socketID );
          }
};
 
#endif // MAINWINDOW_H
 
 

Может опять что-то накосячил? =)
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.239 секунд. Запросов: 23.