LINUX.ORG.RU

как связать Qt и non-Qt?


0

0

Была программа на c++, приделал к ней гуи на Qt. Чтобы изменения некоторых переменных происходили налету, сделал слоты и включил заголовки классов из программы с логикой в кт-шный .cpp. Иерархия сорсов такова, что логика лежит в src/ а gui в src/gui/. Так вот, первая проблема: automake компилит сорцы из src/ как в src/*.o так и в src/gui/*.o, поэтому оно компилится и запускается, но изменения значений переменных из логической части не происходит, видимо потому что Qt-application слинкована с объектниками из src/gui, а не из src/

Пытался линковать вручную с src/*.o, а также изменял в src/gui/gui.pro OBJECTS = blabla.o на OBJECTS = ../blabla.o, пишет 'undefined reference'.

В гугле решения этой, казалось бы стандартной проблемы не нашел.

anonymous
Ответ на: комментарий от max_posedon

Такой вариант тоже рассматривал, но тогда придется слишком много менять в не-qt части (как минимум в корне переписывать не-qт-шный main). А gui и так собирается qmake-ом, с этим проблем нет.

anonymous
()
Ответ на: комментарий от alex_custov

Вызываются, предупреждений нет, более того - переменные даже изменяются как надо, но только "копии" из того объектника, который слинковался в qt-директории. А в основной программе не меняются. PS: сорри за может быть непрофессиональную терминологию, я надеюсь суть понятна.

anonymous
()
Ответ на: комментарий от alex_custov

Сейчас это невозможно. Если вкратце, то что-то вроде

src/nonqt.h:
-----

#include <string>
class NonQt
{
   // ...
public:
   static string var;
}

src/nonqt.cpp:
-----

#include "nonqt.h"
int NonQt::var = "nonqt"
int main (int argc, char **argv)
{
   // ...
   for (int i=0; i<LARGENUMBER; i++)
   {
       // do something ...
       cout << NonQt::var;                   // (1)
   }
}


src/gui/gui.cpp:
----

#include "../nonqt.h"
Gui::Gui(QWidget *parent : QDialog(parent)
{
   // ...
   connect( aSpinBox, SIGNAL(valueChanged(int)), this, SLOT(change_var()));
}

Gui::change_var()
{
   NonQt::var = aSpinBox->value();
   cout << NonQt::var;                      //(2)
}


Тогда если во время выполнения цикла изменится NonQt::var (через aSpinBox) то изменение видно только в (2), но не в (1).



anonymous
()
Ответ на: комментарий от anonymous

PS там конечно static int var (хотел сначала присваивать var="qt", var="nonqt" для наглядности, и в процессе забыл)

anonymous
()
Ответ на: комментарий от anonymous

> Тогда если во время выполнения цикла изменится NonQt::var (через aSpinBox)
> то изменение видно только в (2), но не в (1).

А чего за ОСь у Вас? Не Mac OS или windoze случайно?

Dselect ★★★
()

Телепаты в отпуске.

> Так вот, первая проблема: automake компилит сорцы из src/ как в src/*.o так
> и в src/gui/*.o,

Makefile.am -- в студию.

> видимо потому что Qt-application слинкована с объектниками из src/gui,
> а не из src/

Так по-видимому или на самом деле?

Dselect ★★★
()
Ответ на: Телепаты в отпуске. от Dselect

>А чего за ОСь у Вас? Не Mac OS или windoze случайно?

linux-2.6.24, gcc-4.1.2 [gcc-4.3.1], automake-1.10.1

>Makefile.am -- в студию.

зачем? стандартные мейкфайлы.am: subdirs - sources - blabla- Мне кажется, проблема в том, что это или недопустимая или очень кривая практика - рассовывать исходники по субдирам как это сделано у меня (когда один файл нужен в нескольких директориях). Вот роюсь в гугле на предмет subdirectories, shared sources, subdirectories linking и .тд. но пока как-то безуспешно.

>Так по-видимому или на самом деле?

как бы в этом я и пытаюсь разобраться. пока что другой причины не вижу, но средство пока так и не найдено.

anonymous
()
Ответ на: комментарий от anonymous

> зачем?

Затем, что в этом форуме не играют в испорченный телефон.

> стандартные мейкфайлы.am:

Стандартные Makefile.am работают.

> Мне кажется, проблема в том, что это или недопустимая или очень кривая
> практика - рассовывать исходники по субдирам как это сделано у меня
> (когда один файл нужен в нескольких директориях).

Ничего недопустимого и кривого в этом нет. Сам часто так делаю, правда,
без subdirs.

> Вот роюсь в гугле на предмет subdirectories, shared sources, subdirectories
> linking и .тд.

Вы объясните толком, что нужно, и как Вы пытаетесь этого добиться. Тогда
кто-нибудь (возможно, я) даст вменяемый ответ.

Dselect ★★★
()
Ответ на: комментарий от Dselect

Вот (исходники см. выше):
---------------
src/Makefile.am:
---------------

SUBDIRS = gui
bin_PROGRAMS = ../bin/nonqtprog
___bin_nonqtprog_SOURCES = nonqt.h nonqt.cpp
AM_CPPFLAGS =-Wall -Wno-return-type -g
AM_LDFLAGS =-Wall -Wno-return-type -g $(LDFLAGS)


-------------------
src/gui/Makefile.am:
-------------------

bin_PROGRAMS = ../../bin/qtprog
______bin_qtprog_SOURCES = main.cpp gui.cpp gui.h ../nonqt.h ../nonqt.cpp
DEFINES = -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED
INCPATH = -I/usr/share/qt4/mkspecs/default -I. -I/usr/include/QtCore	\
-I/usr/include/QtCore -I/usr/include/QtGui -I/usr/include/QtGui		\
-I/usr/include -I. -I../.. -I..
AM_CPPFLAGS =-Wall -Wno-return-type -g $(INCPATH)
LIBS += -L/usr/lib -lQtGui -L/usr/lib -L/usr/X11R6/lib		        \
-lpng -lSM -lICE -pthread -lXi -lXrender -lXrandr -lXfixes		\
-lXcursor -lXinerama -lfreetype -lfontconfig -lXext -lX11 -lQtCore -lz	\
-lm -pthread -lgthread-2.0 -lrt -lglib-2.0 -ldl -lpthread
AM_LDFLAGS =-Wall -Wno-return-type -g 


Пока что не смог научить automake использовать объектники из src/
 (вместо этого они компилятся дважды - в src/ и в src/gui)

anonymous
()
Ответ на: комментарий от anonymous

>http://www.tsunanet.net/autotroll/

Натыкался на него в своих поисках, но понадеялся, что можно всё с меньшими телодвижениями сделать. Надо посмотреть.

anonymous
()
Ответ на: комментарий от anonymous

Сначала разберёмся с automake'ом, хотя к Вашей проблеме он не имеет ни
малейшего отношения.

> bin_PROGRAMS = ../bin/nonqtprog

Чего-чего ЦК? (C)

> LIBS += -L/usr/lib -lQtGui -L/usr/lib -L/usr/X11R6/lib                  \
> -lpng -lSM -lICE -pthread -lXi -lXrender -lXrandr -lXfixes              \
> -lXcursor -lXinerama -lfreetype -lfontconfig -lXext -lX11 -lQtCore -lz  \
> -lm -pthread -lgthread-2.0 -lrt -lglib-2.0 -ldl -lpthread

За намертво зашитые библиотеки и пути к ним -- 10 нарядов вне очереди.

Для начала -- напишем по-человечески Makefile.am

bin_PROGRAMS = nonqtprog qtprog

nonqtprog_SOURCES = nonqt.h nonqt.cpp
nonqtprog_CXXFLAGS = -Wall -Wno-return-type -g

qtprog_SOURCES = gui/main.cpp gui/gui.cpp gui/gui.h nonqt.h nonqt.cpp
# добавить в configure.ac AC_CHECH_HEADER 
qtprog_CPPFLAGS = -Igui $(QT_CFLAGS)
# добавить в configure.ac нужные AC_CHECH_LIB
qtprog_LDADD = $(QT_LIBS) 

> Пока что не смог научить automake использовать объектники из src/
> (вместо этого они компилятся дважды - в src/ и в src/gui)

Вообще-то это правильно, поскольку флаги компиляции -- разные, разным
_может_ быть и результат. Я понимаю, в Вашем случае это не так, но 
automake занимается сборкой, а не семантическим анализом кода.

Есть 2 способа:

Первый годится, если не используется libtool:

bin_PROGRAMS = nonqtprog qtprog

nonqtprog_SOURCES = nonqt.h nonqt.cpp
nonqtprog_CXXFLAGS = -Wall -Wno-return-type -g

qtprog_SOURCES = gui/main.cpp gui/gui.cpp gui/gui.h nonqt.h
# добавить в configure.ac AC_CHECH_HEADER 
qtprog_CPPFLAGS = -Igui $(QT_CFLAGS)
# добавить в configure.ac нужные AC_CHECH_LIB
qtprog_LDADD = nonqt.o $(QT_LIBS) 
#              ^^^^^^^

Второй -- более простой и универсальный, собираем из общих исходников
статическую библиотеку:

bin_PROGRAMS = nonqtprog qtprog

noinst_LIBRARIES = libnonqtprog.a
libnonqtprog_a_SOURCES = nonqt.h nonqt.cpp
libnonqtprog_a_CXXFLAGS = -Wall -Wno-return-type -g

nonqtprog_SOURCES =
nonqtprog_LDADD = libnonqtprog.a

qtprog_SOURCES = gui/main.cpp gui/gui.cpp gui/gui.h nonqt.h
# добавить в configure.ac AC_CHECH_HEADER 
qtprog_CPPFLAGS = -Igui $(QT_CFLAGS)
# добавить в configure.ac нужные AC_CHECH_LIB
qtprog_LDADD = libnonqtprog.a $(QT_LIBS) 
#              ^^^^^^^^^^^^^^


Dselect ★★★
()
Ответ на: комментарий от anonymous

> -lm -pthread -lgthread-2.0 -lrt -lglib-2.0 -ldl -lpthread
^^^^^^^^
А GUIня случайно не в отдельном потоке выполняется?

Dselect ★★★
()
Ответ на: комментарий от Dselect

>Сначала разберёмся с automake'ом

Очень поучительно, спасибо. Привел аутомейки в порядок.

Оказывается, тут консольная программа (та что nonqtprog) вызывается кутишной через system("nonqtprog") (консольный код был оставлен абсолютно без изменений, потому что есть древние скрипты, которые работают с консольной версией программы). Поэтому весь этот топик теряет смысл :)

>За намертво зашитые библиотеки и пути к ним -- 10 нарядов вне очереди.

Догадывался, что делаю что-то не так, когда копипастил туда выхлоп qmake-a.

ПС: я правильно понимаю, что теперь правильно было бы привязать оба варианта (qt и консольный) к статической библиотеке, чтобы они через нее "общались"?

anonymous
()
Ответ на: комментарий от anonymous

IPC?

> ПС: я правильно понимаю, что теперь правильно было бы привязать оба
> варианта (qt и консольный) к статической библиотеке, чтобы они через
> нее "общались"?

Смотря что понимать под "общались". Если у Вас есть 2 отдельных процесса
(один -- GUI, qtprog, другой -- собственно полезная нагрузка, nonqtprog),
то нет. Надо пользовать какое-нибудь IPC. Если собрать обе части в один
бинарник (соответственно, будет только один процесс), то можно и с
библиотекой (а можно и без). Но если программа многопоточная (судя по
-pthread -- таки да), то надо аккуратно. Тот код, что Вы привели в пример,
точно работать не будет, потому что у Вас при доступе к общим данным
(статическому члену класса) нет блокировок (хотя для простого int'а
сойдут и атомарные операции).

Dselect ★★★
()
Ответ на: IPC? от Dselect

Кажется, теория начинает немного проясняться. А ведь были чисто интуитивные сомнения по поводу общего использования статического члена класса (хотя в этом конкретном случае чтение и запись достаточно удалены друг от друга во времени).

Буду курить "shared memory".

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.