Russian Qt Forum

Qt => Установка, сборка, отладка, тестирование => Тема начата: G-virus от Февраль 06, 2010, 00:35



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

Точнее он запускается, принимает 1 сообщение и программа завершает работу


Название: Re: Как максимально оптимизировать размер EXE при статической линковке
Отправлено: kibsoft от Февраль 07, 2010, 15:15
Если я правильно понял, и GUI тебе не нужен, то вместо QApplication используй QCoreApplication, тогда меньше будет весить exe..


Название: Re: Как максимально оптимизировать размер EXE при статической линковке
Отправлено: kibsoft от Февраль 07, 2010, 19:58
А еще более параноидальный способ получить малый exe - это взять исходники нужных классов с Qt и всунуть их в проект))
Незнаю будет ли это работать, т.к. еще возможно будут требоваться другие классы, нужные для работы Qt приложения.


Название: Re: Как максимально оптимизировать размер EXE при статической линковке
Отправлено: G-virus от Февраль 08, 2010, 15:21
А еще более параноидальный способ получить малый exe - это взять исходники нужных классов с Qt и всунуть их в проект))
Незнаю будет ли это работать, т.к. еще возможно будут требоваться другие классы, нужные для работы Qt приложения.

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

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



Название: Re: Как максимально оптимизировать размер EXE при статической линковке
Отправлено: kuzulis от Февраль 08, 2010, 15:30
Поищите на этом форуме решение + поищите на crossplatform.ru

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

Вот для этого форума пост: http://www.prog.org.ru/topic_11251_0.html
смотрите там (тык) в ответе №3 :)
вот этот (тык) приведет вас на кроссплатформ.ру и там смотрите сообщение №38


Название: Re: Как максимально оптимизировать размер EXE при статической линковке
Отправлено: kibsoft от Февраль 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().


Название: Re: Как максимально оптимизировать размер EXE при статической линковке
Отправлено: G-virus от Февраль 08, 2010, 21:03
Вот нарыл в документации(метод exec()):

а вот этот QTimer с 0 таймаутом как использовать? или второй способ. Можете фрагмент кода прислать? :)


Название: Re: Как максимально оптимизировать размер EXE при статической линковке
Отправлено: kibsoft от Февраль 08, 2010, 23:19
А код большой у тебя? Может выложишь, а то не видя код думать... Хотя бы опиши что и куда отсылается..


Название: Re: Как максимально оптимизировать размер EXE при статической линковке
Отправлено: G-virus от Февраль 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


Название: Re: Как максимально оптимизировать размер EXE при статической линковке
Отправлено: BRE от Февраль 09, 2010, 07:28
Ты консольную программу хочешь сделать?
Тогда вместо QApplication используй QCoreApplication и в .pro файле укажи QT -= gui.


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

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


Название: Re: Как максимально оптимизировать размер EXE при статической линковке
Отправлено: kuzulis от Февраль 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();
...

или в чем проблема?


Название: Re: Как максимально оптимизировать размер EXE при статической линковке
Отправлено: G-virus от Февраль 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 прога. Уже не знаю как объяснять))))


Название: Re: Как максимально оптимизировать размер EXE при статической линковке
Отправлено: kuzulis от Февраль 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();
}



Название: Re: Как максимально оптимизировать размер EXE при статической линковке
Отправлено: G-virus от Февраль 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
 
 

Может опять что-то накосячил? =)


Название: Re: Как максимально оптимизировать размер EXE при статической линковке
Отправлено: BRE от Февраль 09, 2010, 21:36
Смотри:
connect(server, SIGNAL(newConnection()), this, SLOT(   mySlot()  )  );
void mySlot( int socketID )

Откуда там возьмется параметр int, да еще и с дескриптором сокета?  ;)


Название: Re: Как максимально оптимизировать размер EXE при статической линковке
Отправлено: G-virus от Февраль 09, 2010, 22:01
Смотри:
connect(server, SIGNAL(newConnection()), this, SLOT(   mySlot()  )  );
void mySlot( int socketID )
Откуда там возьмется параметр int, да еще и с дескриптором сокета?  ;)

А как его тогда правильно вписать я че-то ниче не пойму ??? У меня просто до этого немного отличалось все, а теперь я запутался


Название: Re: Как максимально оптимизировать размер EXE при статической линковке
Отправлено: kuzulis от Февраль 09, 2010, 23:42
1. Неправильный слот mySlot(int socketID)!!! Тут не нужен ID!!!
2. Для получения входящего сокета в методе mySlot() необходимо в данном сдучае использовать: QTcpSocket *clientConnection = server->nextPendingConnection();
3. Посмотрите наконец примеры в \qt\examples\network\fortuneserver\
4. Читайте ассистента и все будет путЁм ! :)

--

Упс... опередили уже :)