PDA

View Full Version : Plugins confusion



Paul Drummond
13th February 2006, 14:25
Does anyone know if it's possible to pass a pointer to the mainwindow of an application (that is, the application's specific subclass of QMainWindow) into a plugin then use the pointer to call methods in the MainWindow? For example, if I define a method in my MainWindow called drawImage(), can I call this from a plugin?

I am getting really confused and have been trying to get my code to work for days now. Rather than go into detail about all the things I have tried, I thought I would ask the general question first, then get to the specifics based on the response (if any).

wysota
13th February 2006, 14:56
Yes, it is possible. Taken that your plugin is represented by an instance of some class:


class SomeIFaceImpl : public QObject, SomeIFace {
Q_OBJECT
public:
SomeIFaceImpl(){ m_mw = 0; }
void storePointer(MyMainWindow *mw){ m_mw = mw; }
void useStoredPointer(){ if(m_mw) m_mw->doSomething(); }
private:
MyMainWindow *m_mw;
};

Paul Drummond
13th February 2006, 15:02
Yes, it is possible.

Excellent. Do you have any idea why my code doesn't work then? I can post some code showing how I have implemented this, but firstly let me explain the problem - it's quicker that way.

I have a MainWindow and a Plugin which is passed the mainwindow pointer - much like your example. The Plugin can use the main window pointer to access data members in the mainwindow. However, if I try to call a function, that's where the problems occur!

In Linux I get a symbol error:

symbol lookup error: libGeMapMSUPlugin.so: undefined symbol:
_ZN10MainWindow6canvasEv

In Windows, the plugin won't even compile which is strange! I get the following link error (link errors in a library - whats going on?):



> make
mingw32-make -f Makefile.Release
mingw32-make[1]: Entering directory `C:/Documents and Settings/pdrummond/Desktop/src/morph/GeMapMSUPlugin'
g++ -c -O2 -O2 -Wall -frtti -fexceptions -DUNICODE -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_NO_DEBUG -DQT_PLUGIN -DQT_QT3SUPPORT_LIB -DQT3_SUPPORT -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREA
D_SUPPORT -I"C:/Qt/4.1.0/include/QtCore" -I"C:/Qt/4.1.0/include/QtGui" -I"C:/Qt/4.1.0/include/Qt3Support" -I"C:/Qt/4.1.0/include" -I"C:/Qt/4.1.0/include/ActiveQt" -I"release" -I"."
-I"C:/Qt/4.1.0/mkspecs/win32-g++" -o release\MSUDevicePlugin.o MSUDevicePlugin.cpp
g++ -mthreads -Wl,-enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc -Wl,-s -Wl,-s -shared -Wl,--out-implib,release\libGeMapMSUPlugin.a -o "release\GeMa
pMSUPlugin.dll" release\MSUDevicePlugin.o release\MSUDeviceIcon.o release\moc_MSUDevicePlugin.o -L"C:\Qt\4.1.0\lib" -lQt3Support4 -lQtGui4 -lQtCore4
Creating library file: release\libGeMapMSUPlugin.a
release\MSUDevicePlugin.o(.text+0x896):MSUDevicePl ugin.cpp: undefined reference to `MainWindow::canvas()'
collect2: ld returned 1 exit status
mingw32-make[1]: *** [release\GeMapMSUPlugin.dll] Error 1
mingw32-make[1]: Leaving directory `C:/Documents and Settings/pdrummond/Desktop/src/morph/GeMapMSUPlugin'
mingw32-make: *** [release] Error 2


Something isn't quite right here! Any ideas?

wysota
13th February 2006, 15:45
Does your project file state that the compilation is a plugin (I think you need both the "plugin" and "dll" options)?

As for Linux, you need to add a switch to the main app to allow plugins to resolve its symbols within the application binary. The switch is "-rdynamic".

You can add it to the project file like this:

QMAKE_LFLAGS += -rdynamic

Remember to rerun qmake afterwards.

Paul Drummond
13th February 2006, 15:59
Does your project file state that the compilation is a plugin (I think you need both the "plugin" and "dll" options)?

I will try the Linux switch tonight (I only have access to windows here at work).

As far as windows goes, I had the "plugin" option defined but not "dll" - I added it, did a make clean, qmake, make and the compile error still occurs:



> make
mingw32-make -f Makefile.Release
mingw32-make[1]: Entering directory `C:/Documents and Settings/pdrummond/Desktop/src/morph/GeMapMSUPlugin'
g++ -c -O2 -O2 -Wall -frtti -fexceptions -DUNICODE -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_NO_DEBUG -DQT_PLUGIN -DQT_QT3SUPPORT_LIB -DQT3_SUPPORT -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREA
D_SUPPORT -I"C:/Qt/4.1.0/include/QtCore" -I"C:/Qt/4.1.0/include/QtGui" -I"C:/Qt/4.1.0/include/Qt3Support" -I"C:/Qt/4.1.0/include" -I"C:/Qt/4.1.0/include/ActiveQt" -I"release" -I"."
-I"C:/Qt/4.1.0/mkspecs/win32-g++" -o release\MSUDevicePlugin.o MSUDevicePlugin.cpp
g++ -c -O2 -O2 -Wall -frtti -fexceptions -DUNICODE -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_NO_DEBUG -DQT_PLUGIN -DQT_QT3SUPPORT_LIB -DQT3_SUPPORT -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREA
D_SUPPORT -I"C:/Qt/4.1.0/include/QtCore" -I"C:/Qt/4.1.0/include/QtGui" -I"C:/Qt/4.1.0/include/Qt3Support" -I"C:/Qt/4.1.0/include" -I"C:/Qt/4.1.0/include/ActiveQt" -I"release" -I"."
-I"C:/Qt/4.1.0/mkspecs/win32-g++" -o release\MSUDeviceIcon.o MSUDeviceIcon.cpp
C:\Qt\4.1.0\bin\moc.exe -DUNICODE -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_NO_DEBUG -DQT_PLUGIN -DQT_QT3SUPPORT_LIB -DQT3_SUPPORT -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREAD_SUPPORT -I"C:/Q
t/4.1.0/include/QtCore" -I"C:/Qt/4.1.0/include/QtGui" -I"C:/Qt/4.1.0/include/Qt3Support" -I"C:/Qt/4.1.0/include" -I"C:/Qt/4.1.0/include/ActiveQt" -I"release" -I"." -I"C:/Qt/4.1.0/m
kspecs/win32-g++" -D__GNUC__ -DWIN32 MSUDevicePlugin.h -o release\moc_MSUDevicePlugin.cpp
g++ -c -O2 -O2 -Wall -frtti -fexceptions -DUNICODE -DQT_LARGEFILE_SUPPORT -DQT_DLL -DQT_NO_DEBUG -DQT_PLUGIN -DQT_QT3SUPPORT_LIB -DQT3_SUPPORT -DQT_GUI_LIB -DQT_CORE_LIB -DQT_THREA
D_SUPPORT -I"C:/Qt/4.1.0/include/QtCore" -I"C:/Qt/4.1.0/include/QtGui" -I"C:/Qt/4.1.0/include/Qt3Support" -I"C:/Qt/4.1.0/include" -I"C:/Qt/4.1.0/include/ActiveQt" -I"release" -I"."
-I"C:/Qt/4.1.0/mkspecs/win32-g++" -o release\moc_MSUDevicePlugin.o release\moc_MSUDevicePlugin.cpp
g++ -mthreads -Wl,-enable-stdcall-fixup -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc -Wl,-s -Wl,-s -shared -Wl,--out-implib,release\libGeMapMSUPlugin.a -o "release\GeMa
pMSUPlugin.dll" release\MSUDevicePlugin.o release\MSUDeviceIcon.o release\moc_MSUDevicePlugin.o -L"C:\Qt\4.1.0\lib" -lQt3Support4 -lQtGui4 -lQtCore4
Creating library file: release\libGeMapMSUPlugin.a
release\MSUDevicePlugin.o(.text+0x896):MSUDevicePl ugin.cpp: undefined reference to `MainWindow::canvas()'
collect2: ld returned 1 exit status
mingw32-make[1]: *** [release\GeMapMSUPlugin.dll] Error 1
mingw32-make[1]: Leaving directory `C:/Documents and Settings/pdrummond/Desktop/src/morph/GeMapMSUPlugin'
mingw32-make: *** [release] Error 2


Here's my pro file:



TEMPLATE = lib
TARGET +=
DEPENDPATH += .
CONFIG += plugin dll config qt exceptions rtti warn_on release
QT += qt3support

# Input
HEADERS += MSUDevicePlugin.h MSUDeviceIcon.h
SOURCES += MSUDevicePlugin.cpp MSUDeviceIcon.cpp


You say on Linux I need to add "-rdynamic" to the main application - do I need to add anything to the main app for windows?

wysota
13th February 2006, 16:04
Unfortunately I can't help you much with windows as I'm not an expert on creating dlls in this environment. You can try the same, but as for now you can't even compile the plugin, so the issue has to be different.It is not a Qt issue in any way, rather a MinGW one. You could try asking the Trolls for help with this, maybe the qmakeconf for MinGW is incorrect.

Paul Drummond
13th February 2006, 16:22
Unfortunately I can't help you much with windows as I'm not an expert on creating dlls in this environment. You can try the same, but as for now you can't even compile the plugin, so the issue has to be different.It is not a Qt issue in any way, rather a MinGW one. You could try asking the Trolls for help with this, maybe the qmakeconf for MinGW is incorrect.

Ok, well thank you very much for your help - you answered my main question - what I am trying to do is possible and the problem lies in compliation/linking issues. Thanks again.

blackliteon
13th February 2006, 16:26
You mean we need point compiler that's we compile dll ?

wysota
13th February 2006, 16:42
You mean we need point compiler that's we compile dll ?

Yes, the compiler has to be aware of this (for whatever the reasons).

Paul Drummond
14th February 2006, 10:24
As for Linux, you need to add a switch to the main app to allow plugins to resolve its symbols within the application binary. The switch is "-rdynamic".

You can add it to the project file like this:

QMAKE_LFLAGS += -rdynamic

Remember to rerun qmake afterwards.

Just an update to let you know this worked perfectly on Linux, thank you. Is this specified anywhere in the documentation?

I still have problems with Windows but I will start a new thread for that as its an issue with DLLs specifically.

wysota
14th February 2006, 10:27
Is this specified anywhere in the documentation?
In Qt documentation? No. I had to dig it out myself from ld docs and other sources when I needed it in my own program.


I still have problems with Windows but I will start a new thread for that as its an issue with DLLs specifically.

You might want to take a look at this thread (http://www.qtcentre.org/forum/showthread.php?t=638), it looks very simmilar to your problem and the source of it is probably the same.

Gabriel
15th February 2006, 10:46
Please note that in order the plugins works in designer in windows the plugin dll must be compiled in release mode only.