Seite 1 von 1

Plug and Paint (Probleme beim Linken)

Verfasst: 29. November 2007 23:42
von glHomeless
Hallo,

Ich wollte das Plug and Paint Beispiel von Qt erweitern. In meinem Interface sollte es ein Zeiger auf das MainWindow geben. Doch bekomme ich linking Probleme. Ich habe folgendes geaendert:

Code: Alles auswählen

class BrushInterface
{
...
void setMainWindow(MainWindow*);
...
}
irgendwo in MainWindow mache ich dann folgendes:

Code: Alles auswählen

if (iBrush)
{
addToMenu(...);
iBrush->setMainWindow(this);
}
Ich habe meinem MainWindow eine neue Funktion hinzugefuegt:
insertDockWidget(...)

Doch wenn ich diese (und nur meine eigene ) Funktion aufrufe (in BrushInterface) bekomme ich folgende Fehlermeldun:

unresolved external symbol ...MainWindow::insertDockWidget(...)
referenced in function
public: virtual void __thiscall BasicToolsPlugin::slotProjectToggled(void)


Ich weiß, dass Linking Fehlermeldungen nervig sein koennen. Doch hier weiß ich nicht, wie ich weiter machen soll???

Danke

Verfasst: 30. November 2007 06:31
von Christian81
Wie wäre es wenn man die Funktion (wenn man sie schon definiert) einfach mal implementiert?

Verfasst: 30. November 2007 13:11
von glHomeless
Also so dumm bin ich auch wieder mal nicht. Selbstverständlich habe ich die Funktion implementiert. Das Programm lässt sich ja auch linken und ausführen. Das Plugin aber lässt sich nicht linken. Ich vermute mal, dass ich was an meinem .pro file was ändern muss. Aber was genau, weiß ich noch nicht ???

Verfasst: 30. November 2007 14:00
von Christian81
Wenn Du die Funktion im Plugin benutzt, muss sie auch im Plugin vorhanden sein (quasi die gleiche Aussage wie oben).

Verfasst: 30. November 2007 14:28
von RHBaum
Und um noch genauer zu werden ....

Jede uebersetzungseinheit die ein object von deine klasse instanziiert mus auch die methoden der Klasse implementieren (also per obj Datei oder per statischer lib einbinden) :-)

Sprich du wirst eine einstanz der klasse "BrushInterface" in deinem Plugin instanzieren (per new oder per lokales/globale variable) .... und deinem plugin hasst die objektdatei ned zugefuegt.

Aber aus designtechnischer Sicht ist hier eh was im argen :-)

wieso heist deine klasse "Interface", wenn sie Methoden implementiert ? Nen interface ist ueblicherweisse eine pure abstrakte klasse, die nur pure virtuale methoden enthaelt.
Und genau damit umgeht man solche probleme .... Man gibt das interface vor, damit kann dann jeder umgehen der den richtigen header kennt.
Und man baut ne Impl dazu, die nur die implementierende (also instanziierende) Uebersetzungseinheit kennt, in den anderen (plugins etc) arbeitet man nur noch mit dem interface, was man soweiso ned instanzieiren kann, sondern nur referenzieren (auf die Impl) ....

Ciao ...

Verfasst: 30. November 2007 15:12
von glHomeless
Danke schon mal für Eure Hilfen. Also mein BrushInterface sieht folgendermaßen aus:

Code: Alles auswählen

class BrushInterface : public Interface
{
...
void setMainWindow(MainWindow*);
...
}
Die Klasse Interface ist rein virtuel (abstrakt). Dieses Plugin wird dann in MainWindow geladen. Da MainWindow selbst eine .exe ist, kann BrushInterface nicht auf MainWindow.cpp zugreifen. Ich habe gerade erfahren, dass man halt das MainWindow nicht nur zu einer exe verarbeiten soll, sondern noch zusätzlich exportieren muss.
Später kann dann BrushInterface es importieren. Es scheint schon etwas komplizierter zu sein. Ich versuche es mal. Vielleicht klappt es.

Verfasst: 30. November 2007 15:47
von RHBaum
1. Namensgebung

wenn speter du oder jemand anders mal den code durchschauen muss. wird der sicherlich wahnsinnig ^^

Klasse Interface ??? wenn du spaeter mal nen anderes Interface brauchst, wie heisst das dann ? Interface2 ? :-)
Also nen Brush soll ja normalerweisse was fuellen oder zeichnen... oder so.
das mindeste waere DrawInterface .... oder alternativ IDraw.
oder GraphicItemInterface oder oder ... keine ahnung was die schnittstelle genau beschreibt.
deine Brush-klasse waere dann eher ne Impl, also BrushImpl ...

Ok, ueber Namensyntax laesst sich streiten, aber konsistente aussagekraeftige Namen haben echt was ...
Es scheint schon etwas komplizierter zu sein
2. Plugins sind definitiv nicht trivial ... Also da gehoert scho ne menge an grundlagenwissen dazu ....

Prinzipiell .... dein Mainwindow scheint ne Huelle / Hauptfenster was weiss ich, fuer deine Application zu sein .... Da soltle auch das Plugin nix, aber auch gar nix drueber wissen ....

Fuer alles was dein Plugin ueber die App wissen muss, und wass die App ueber das Plugin wissen muss, sollte es Interfaces, und nur Interfaces fuer geben .....
Geht ned immer .... grad am beispiel von der QT, weil QWidget kein reines Interface ist ....

Trotzdem sollt man abhaengigkeiten so gering wie moeglich halten ....
Irgendwie willst du scheinbar in dem Plugin auf was malen, oder ein neues Fenster / Widget aufmachen, dafuer brauchst das Mainwindow.. ..

Nun schau dir fuer deine Funktionen die im Plugin verwendest, genau an was fuer Typen du vom Paramaeter du Brauchst ?
Mainwindow (ich nehm an deine eigene Impl von QMainWindow) sicher nicht ....
Also maximal QMainWindow .... aber selbst das nur wenn wirklich funktionen auf Mainwindow Ebene brauchst.
Ich vermute fuer dich wuerde QWidget langen ....
Also wenns geht immer so weit runter wie moeglich ... um so weniger das plugin wissen muss, um so besser.

Code: Alles auswählen

class BrushImpl : public IDraw
{
...
void setMainWindow(QWidget *);
...
}
So saehs vielleicht bei mir aus ....
und fuer QWidget brauchts keine impl, da du es eh nur referenzierst, also wuerde in deinem plugin ein
#include <QWidget>
eigentlich langen ....

CIao ...

Verfasst: 30. November 2007 16:09
von glHomeless
Danke noch mal.

In Wirklichkeit habe ich selbstverständlich bessere Namen gegeben. Um möglichst genau bei dem Beispiel von Qt zu bleiben, habe ich vereinfacht dargestellt.

Was ich möchte ist folgendes:
1) Ein Plugin sollte ein Dockwidget beim MainWindow einhägen können.
2) Ein Plugin sollte über einen MainWindow-Zeiger auf andere Plugins zugreifen können. (Die andere Plugins sind in MainWindow in einer Liste drin)


Deshalb brauche ich schon Funktionalitäten von MainWindow. Ich werde später dann eine weitere Klasse schreiben wie z.B. PluginManager, die dann diese Extra Funktionen übernimmt. (Habe es schon versucht, bekomme ähnlich Fehler).

Kannst du mir weiter helfen?

Verfasst: 30. November 2007 17:30
von solarix
glHomeless hat geschrieben: 1) Ein Plugin sollte ein Dockwidget beim MainWindow einhägen können.
Nein, sollte es nicht, denn
Da soltle auch das Plugin nix, aber auch gar nix drueber wissen ....
da geselle ich mich an die Seite von RHBaum..
Warum kann das MainWindow nicht via Interface die Infos abfragen, die es benoetigt, oder es via Signal/Slot erhalten?
glHomeless hat geschrieben: 2) Ein Plugin sollte über einen MainWindow-Zeiger auf andere Plugins zugreifen können. (Die andere Plugins sind in MainWindow in einer Liste drin)
nein, sollte es schon wieder nicht... und am wenigsten ueber die Liste des MainWindows/PluginManagers..., denn zirkulaere Abhaenigkeiten sind sch...

Reichen Signals/Slots nicht, um Auftraege/Infos/was-auch-immer in der Applikation bekannt zu geben?

Verfasst: 30. November 2007 17:55
von glHomeless
Danke nochmals für die hilfreichen Antworten.

Ok. Bevor ich mein Ding ausprobiere, versuche ich am Wochenende eure Ideen umzusetzen. Ich denke mit signal/slots sollte es doch wirklich gehen.
Werde dann das Ergebnis hier posten.

Bis dann