
Plug-ins sind ein eleganter Mechanismus, der einem Browser zusätzliche Funktionen verleiht. Sie sind klein, damit schnell herunterzuladen und verbinden Browser-Funktionen mit unbeschränkten Zugriffsmöglichkeiten auf die unterliegende Plattform. Wegen ihrer Vielseitigkeit lässt sich nahezu jede Störung im Zusammenspiel zwischen WWW-Server und lokalem Rechner beseitigen. Außerdem können sie etwa Daten applikationsspezifisch darstellen, lokale Anwendungen wie Microsoft Word fernsteuern oder Inhalte für einen Drucker ohne Einflussnahme durch den jeweiligen Browser sauber aufbereiten.
Die Alternative zu Plug-ins sind im Normalfall Java-Applets. Während die benutzerseitige Bearbeitung von Daten mit Java-Applets gut realisierbar ist - allerdings mit dem Nachteil langer Download-Zeiten wegen deren Größe -, gerät schon die Steuerung lokaler Anwendungen mit Java zu einem komplexen Unterfangen. Selbst solch einfache Dinge wie das Ausdrucken von Inhalten können je nach der lokal installierten Version von Java zu einem regelrechten Abenteuer werden.
Der größte Nachteil ist, dass der Benutzer dem Autor des Plug-in blind vertrauen muss. Zwar kann der Autor den Code mit einem Zertifikat signieren, aber kein normaler (das heißt paranoider) Administrator eines Firmennetzwerkes dürfte dem wirklich vertrauen, sofern er es nicht selbst ausgestellt hat. Hinzu kommt, dass Plug-ins plattformspezifisch sind und damit nicht ohne Weiteres unter verschiedenen Betriebssystemen funktionieren. Außerdem hat Netscape die Plug-in-Schnittstelle definiert, was neuere Versionen der microsoftschen Browser nicht mehr unterstützen. Stattdessen existiert ActiveX Control, über das sich Netscape-Plug-ins in den Browser integrieren lassen (siehe Kasten Das ActiveX-Control für den IE).
Damit beschränkt sich der Einsatz von selbst geschriebenen Plug-ins im Normalfall auf die innerbetriebliche Umgebung. Gerade hier können sie ihre Stärken ausspielen, da es sich in der Regel um eine nahezu homogene Umgebung handelt.
Wer Plug-ins programmieren möchte, muss sich zuerst mit deren Lebenszyklus auseinander setzen. Grob betrachtet gibt es hier vier Abschnitte:
Während nur der dritte dieser Lebensabschnitte für den Benutzer relevant ist, muss ein Programmierer alle im Auge behalten.
Innerhalb einer HTML-Seite kann der Entwickler beliebige Ressourcen referenzieren, indem er als HTML-Tag entweder EMBED oder OBJECT verwendet (Details unter Die Einbettung des Plug-in). Für die gewünschte Darstellung im Browser sorgt innerhalb des Tag ein MIME-Type (Multipurpose Internet Mail Extensions), der zur Identifikation des passenden Plug-in dient. Der Programmierer definiert ihn beim Erzeugen des Plug-in - im Falle privater MIME-Types beginnen diese immer mit X-. Beim Start erwartet der Browser die Plug-ins innerhalb eines spezifischen Verzeichnisses, das je nach Art des Hauses einen anderen Ort hat (siehe Kasten Wo sucht der Browser nach Plug-ins?). Für jedes Plug-in speichert er in einer Tabelle, welche MIME-Types er darstellen kann. Falls er später auf einen stößt, weiß er, welches Plug-in er zu laden hat. Je nach Browser kann eine Anpassung der verwendeten Plug-ins zur Laufzeit stattfinden.
Bei jeder Referenz entsteht eine eigene Instanz des Plug-in. Damit geht das Laden in zwei Schritten vor: Zuerst holt der Browser den Code von der Festplatte und ruft die Plug-in-globale Initialisierungsfunktion NP_Initialize() auf, mit der er Ressourcen belegt, die alle Instanzen des Plug-in gemeinsam benutzen.
Für jede Instanz in Folge aktiviert er die Funktion NPP_New(), die die jeweilige Instanz initialisiert und erhält unter anderem die im HTML-Text definierten Parameter.
Nun beginnt die interessante Zeit im Leben des Plug-in. Je nach Aufgabe muss es jetzt innerhalb seines Bereiches zeichnen, vom Server Daten empfangen, Statusinformationen in die Statuszeile des Browsers schreiben oder anderes implementieren. Da es völlig ungeschützt im Kontext der Browser-Applikation läuft, kann es sämtliche Funktionen der unterliegenden Plattform verwenden; für die erwähnten Aufgaben reichen aber die Browser-internen.
Das Zeichnen von Informationen innerhalb des in der HTML-Seite reservierten Bereiches geschieht plattformabhängig. Für alle Plattformen gilt, dass die Funktion NPP_SetWindow() den Bereich setzt, innerhalb dessen das Plug-in zeichnen darf. Die übergebene plattformspezifische Struktur muss das Plug-in für die weitere Verwendung aufbewahren.
Unter Windows soll eine neue Funktion zur Bearbeitung von Events entstehen, die an den Bereich (das Fenster) gehen. Dies geschieht über einen Mechanismus, der Subclassing heißt. Die neuen Funktion wartet auf das Ereignis WM_PAINT, das zum Neuzeichnen auffordert. Dieser Teil ist Standard-Windows-Programmierung; Details hierzu finden sich unter [1].
Zu den integralen Funktionen gehört der Empfang von Daten durch das Plug-in. Dies geschieht im Wesentlichen durch den wechselseitigen Aufruf zweier Funktionen, die dem Plug-in die Daten übermitteln: NPP_WriteReady(), fragt das Plug-in, wie viel Daten es zu übernehmen in der Lage ist, NPP_Write() übergibt dann maximal diese Menge an Daten (es können durchaus weniger Daten sein). Liegen neue Daten an, ruft der Browser erneut NPP_WriteReady() gefolgt von NPP_Write() auf, bis der Strom von Daten versiegt. Weiterhin gibt es noch NPP_NewStream() bei der Initialisierung und NPP_DestroyStream() beim Schließen des Stroms, die dem Plug-in die Chance geben, auf das jeweilige Ereignis zu reagieren.
Zum Anzeigen einer Meldung in der Statuszeile bietet der Browser NPN_Status() an, der eine Zeichenkette zur Anzeige übernehmen kann. Der Browser stellt diese Meldung Browser-typisch so lange dar, bis eine neuere Meldung (auch von anderen Teilen der angezeigten Seite) diese überschreibt.
Wenn der Benutzer die Seite schließt, auf der sich die Plug-in-Instanz befindet, löst der Browser NPP_Destroy() aus. Hier kann der Programmierer instanzspezifische Aufräumarbeiten durchführen.
Falls es sich um die letzte Instanz des Plug-in handelt, kann der Browser mit NP_Shutdown() analog zur globalen Initialisierungsfunktion die von den Instanzen des Plug-in gemeinsam benutzten Ressourcen wieder freigeben.
Prinzipiell folgt das Schreiben eines Plug-in für fast alle Plattformen dem beschriebenen Weg. Dieser Beitrag beschränkt sich auf Microsoft Windows und auf ein einfaches Plug-in, das innerhalb der Statuszeile die Höhe und Breite seines eigenen Bereichs ausgibt. Für komplexere Interaktionen sei auf die Dokumentation im Web verwiesen, innerhalb derer die Verwendung der im Kasten Plug-in-Funktionen erwähnten Funktionen zum Drucken und zum Kommunizieren mit dem Server detailliert erklärt sind.
Für die Entwicklung eignen sich sowohl das Software Development Kit (SDK) von Mozilla als auch ein älteres von Netscape (siehe Fundorte im Web). Wer Mozillas SDK wählt, muss zuerst den gesamten Quelltext übersetzen, da das Kit die notwendigen Konfigurationsinformationen bestimmt. Die Alternative, das SDK von Netscape, stammt zwar aus dem Jahr 1997, unterstützt aber im Prinzip die gleichen Schnittstellen. Das Beispiel bezieht sich auf Letzteres.
Im SDK verbirgt sich ein Verzeichnis mit Beispielen, die man sowohl für erste Gehversuche modifiziert als auch als Basis für die spätere Entwicklung verwenden kann; besonders empfehlenswert ist hierfür das Unterverzeichnis WinTemplate. Für eine erfolgreiche Plug-in-Entwicklung muss man npwin.cpp aus dem Verzeichnis Common einbinden, um die Implementierung der Schnittstellenfunktionen zu erhalten.
Zum größten Teil besteht das Beispiel-Plug-in aus leeren Funktionsrümpfen (siehe Listing 1), was damit zusammenhängt, dass es abgesehen von der Ausgabe einer Statusmeldung keine weitere Funktion hat. Es zeigt aber, wie einfach grundsätzlich das Schreiben eines vollständigen Plug-in ist. Ein Plug-in mit komplexerer Funktionen dürfte im Normalfall ebenso übersichtlich bleiben; allerdings benötigt jedes nichttriviale Plug-in einen instanzspezifischen Speicherbereich. Dessen Verwaltung in NPP_New() und NPP_Destroy() erfordert aber nur einige zusätzliche Zeilen, denn der Zeiger auf diesen Bereich erscheint in der in jedem Funktionsaufruf mitgegebenen Instanzstruktur.
Ausgehend von dem Beispiel kann jeder einfach iterativ die Funktionen erweitern. Einfache Varianten sind sind
Angesichts der Tatsache, dass das Plug-in ohne Sicherheitsbeschränkungen läuft, sind die einzigen Grenzen durch das eigene Vorstellungsvermögen und die Programmiermöglichkeiten unter Windows gegeben. Eine zusätzliche Randbedingung gilt unter Windows: der Name des Plug-in muss mit NP beginnen, mit .DLL enden und darf nur 8 + 3 Zeichen lang sein. Dies beschränkt die sinnvolle Namensgebung auf sechs Zeichen, was aber für den normalen Benutzer irrelevant sein dürfte.
Zwar zwingt die Kürze des Artikels zum Unterschlagen einiger Kleinigkeiten, das Beispiel mag aber dennoch zeigen, dass das Schreiben eines Browser-Plug-in kein Hexenwerk ist, sondern nur eines Quäntchens Handwerkskunst bedarf, damit es zu brauchbaren Ergebnissen kommt.
Dies eröffnet eine weites Feld für die Unterstützung von webbasierten Applikationen im innerbetrieblichen Umfeld, was das Leben sowohl der Entwickler als auch der Benutzer ohne großen Aufwand deutlich vereinfachen kann. Sogar die Administration der Systeme innerhalb einer Organisation lässt sich komfortabler gestalten, da die Installation eines Plug-in nur einen Bruchteil dessen bedeutet, was die Installation einer Java Virtual Machine für verschiedene Browser mit sich bringt.
Zu den unbestreitbaren Nachteilen gehört: Plug-ins können ungeschützt auf das unterliegende System zugreifen, deshalb sollen sie außerhalb des eigenen Intranets im Normalfall nicht erlaubt sein. Für die skizzierten Einsatzfelder hat dies nur eine geringe Bedeutung. Mal als Nachteil, mal als Vorteil ist die plattformspezifische Programmierung zu sehen: der Programmierer muss sich mit dem System auskennen, um die gewünschten Ziele zu erreichen, die dann aber sehr weit reichen können. Java bietet mit seiner Plattformunabhängigkeit deutliche Vorteile, allerdings zu einem vergleichsweise hohen Preis.
Dr. Joachim Baumann
arbeitet im Bereich Web-Applikationsentwicklung der Firma junidas GmbH (www.junidas.de).
Literatur
[1] Charles Petzold, Programming Windows. The definitive guide to the Win32 API, Microsoft Press
| iX-TRACT |
|
Dieser Text ist der Zeitschriften-Ausgabe 04/2004 von iX entnommen.
iOS, Android, Windows Phone 7 und HTML5 - das neue Sonderheft von heise Developer führt Einsteiger und Profis in die Programmierung mobiler Geräte ein.