com-programmierung mit visual basic 6 michael willers [email protected] microsoft gmbh
TRANSCRIPT
Agenda
Warum COM und VB? Wie funktioniert‘s? Wo gibt‘s weitere Info‘s?
Warum COM und VB?
Sie können unter VB objektorientiert arbeiten
• Besseres Design
• Code wird wartungsfreundlicher
Sie können objektorientiert binäre Komponenten entwickeln, die über einem einheitlichen Mechanismus kommunizieren
• sprachneutral
• Baukastensystem
Mit VB können Sie Klassen erstellen• Werden als cls-Dateien gespeichert
Ein Objekt ist die Instanz einer Klasse• Instanz wird mit „Set... = New...“ zur
Laufzeit erstellt Kapselung
• Code und Daten werden gemeinsam in ein Objekt „gepackt“
VB-Klassen und Kapselung• Properties stellen die Daten dar
• Methoden und Events stellen den Code dar
Wie funktioniert‘s?Objektorientierung unter VB - Klassen
Events ermöglichen „asynchrones“ Arbeiten• Rückmeldung während der Abarbeitung einer
Methode
Jede VB-Klasse feuert zwei Events• Initialize: Instanz einer Klasse wird angelegt
• Terminate: Instanz einer Klasse wird „entsorgt“
Für jede Klasse können eigene Events definiert und gefeuert werden
Aufrufer kann auf zwei Arten reagieren• Event-Routine
• CallBack-Mechanismus
Wie funktioniert‘s?Objektorientierung unter VB - Events
Wann benutzt man Event-Handler, wann Callback-Funktionen?
• Event• Die Klasse, die den Event auslöst, benötigt keine
Informationen über den Aufrufer
• Lose Kopplung
• Connection-Points „behind the scenes“
• Callback• Die Klasse, die den Event auslöst, benötigt
detaillierte Informationen über den Aufrufer
• „Handshake“ zwischen Klasse und Aufrufer
Wie funktioniert‘s?Objektorientierung unter VB - Events
Demo
Wie funktioniert‘s?Schnittstellenorientierte Programmierung
Public Sub Method1()Dim i as Integeri = i + 1
End Sub
Public Sub Method2(x as Double)x = x + 99.25
End Sub
Public Function Method3() as IntegerDim i as Integeri = 42Method3 = i
End Function
Public Sub Method1()Dim i as Integeri = i + 1
End Sub
Public Sub Method2(x as Double)x = x + 99.25
End Sub
Public Function Method3() as IntegerDim i as Integeri = 42Method3 = i
End Function
Public Sub Method1()End Sub
Public Sub Method2(x as Double)End Sub
Public Function Method3() as IntegerEnd Function
Public Sub Method1()End Sub
Public Sub Method2(x as Double)End Sub
Public Function Method3() as IntegerEnd Function
Schnittstelle
Klasse
Trennung von Definition und Implementation
Die Zuordnung zwischen Klasse und Schnittstelle erfolgt über implements• Die Klasse muss dann die Schnittstelle vollständig
implementieren
Unterschiedliche Klassen können die gleiche Schnittstelle implementieren• Polymorphie!
• Neue Klassen können hinzugefügt werden und vorhandener Code bleibt lauffähig Dim car as ICar
car.Hoot
Eine Klasse kann mehrere Schnittstellen implementieren
Wie funktioniert‘s?Schnittstellenorientierte Programmierung
Was tun, wenn eine Schnittstelle, die schon im Einsatz ist, geändert werden muss?• Neue Schnittstelle mit der neuen Funktionalität
erstellen und implementieren!
• Vorhandener Code bleibt lauffähig
• Clients können nach der neuen Schnittstelle fragen oder die alte Funktionalität benutzen• Dim car as ICar, car2 as ICar2
Set car = new CFordIf TypeOf car is ICar2 then
Set car2 = carcar2.PowerHoot
Elsecar.Hoot
End If
Wie funktioniert‘s?Versionierung von Schnittstellen
Demo
Dim App as New MyObject.Obj1• Explizite Zuweisung per SET nicht
erforderlich
• Aber: Bei jeden Aufruf wird geprüft, ob ein gültiger Objekt-Verweis existiert• ggf. wird eine neue Instanz erzeugt!!
Set App = New MyObject.Obj1• Verweis auf ein Objekt wird einmalig
erstellt
• Verweis bleibt erhalten, bis der Aufruf von Set App = nothing erfolgt oder Scope verlassen wird
Wie funktioniert‘s?Wann rufe ich New... auf?
Es erfolgt der Aufruf von Set ... = nothing• Objekt wird unmittelbar nach dem Aufruf entsorgt
( Referenzen beachten)• ACHTUNG: Über Terminate-Event ist keine
Fehlerbehandlung möglich!!!
• Wenn man diese braucht, sollte man das Objekt explizit mit Set ... = nothing entsorgen
Ein Objekt ist global innerhalb eines Moduls oder einer Methode deklariert:• Objekt wird beim Verlassen des Moduls „entsorgt“
• wird Objekt mit „Set...= New“ oder CreateObject neu angelegt wird das „alte Objekt“ automatisch entsorgt
Wie funktioniert‘s?Wann wird ein Objekt „entsorgt“?
Frühe Bindung
• Objektverweise sind zur Compilezeit bekannt• Dim app as MyApp.Class1
Set app = New MyApp.Class1 oderSet app = CreateObject(„MyApp.Class1“)
Späte Bindung
• Objekttyp ist erst zur Laufzeit bekannt• Dim app as Object
Set app = CreateObject(„MyApp.Class1“)
• Automation ( IDispatch)
Wie funktioniert‘s?Frühe und späte Bindung
Demo
Eine COM-Schnittstelle ist die logische Gruppierung von Methoden
Eine Co-Klasse ist eine Klasse, die eine oder mehrere Schnittstellen implementiert
Ein COM-Objekt ist die Instanz einer Co-Klasse
Eine Komponente ist eine binäre Datei, die eine oder mehrere Co-Klassen enthält
• wird oft auch mit COM-Server bezeichnet
Wie funktioniert‘s?COM-Grundsätzliches
COM-Schnittstellen werden mit der Interface Definition Language IDL beschrieben• Visual Basic macht dies „behind the scenes“
Eine TypeLibrary ist die Beschreibung einer Schnittstelle in binärer Form• Wird mit dem MIDL-Compiler aus einer IDL-
Datei erstellt
• Liegt als separate TLB-Datei vor oder ist als Ressource integriert
• Visual Basic macht auch dies „behind the scenes“
Wie funktioniert‘s?Beschreibung von Schnittstellen
In Visual Basic können TLB-Dateien nur mit der Enterprise-Edition erstellt werden• Project Properties Remote Server files
Visual Basic bindet TLB-Datei als Ressource in den COM-Server ein
Um Informationen zu Schnittstellen zu erhalten, kann man TLBs referenzieren
Referenzieren in VB• Project References
• Wenn die TLB nicht nicht registriert ist, wird das an dieser Stelle implizit gemacht!
• Ansehen mit dem Objektkatalog
Wie funktioniert‘s?Beschreibung von Schnittstellen
OLEVIEW ist ein praktisches Werkzeug, um die IDL zu „lernen“
In größeren Projekten sollten Sie die IDL separat erstellen und TLB-Dateien zur Verfügung stellen
• benutzen Sie Visual C++ zum Erstellen von IDL und TLB
• insbesondere in „gemischtsprachigen“ Umgebungen“
Wie funktioniert‘s?COM-Schnittstellen, Tipps & Hinweise
smallsmall
longlong
hyperhyper
IDLIDL C++C++ JavaJava
shortshort
charchar
longlong
__int64__int64
bytebyte
intint
longlong
shortshort shortshort
Visual BasicVisual Basic
N/AN/A
LongLong
N/AN/A
IntegerInteger
unsigned smallunsigned small
unsigned longunsigned long
unsigned hyperunsigned hyper
unsigned shortunsigned short
unsigned charunsigned char
unsigned longunsigned long
unsigned __int64unsigned __int64
bytebyte
intint
longlong
unsigned shortunsigned short shortshort
ByteByte
N/AN/A
N/AN/A
N/AN/A
floatfloat
doubledouble
floatfloat
doubledouble
floatfloat
doubledouble
SingleSingle
DoubleDouble
charchar
unsigned charunsigned char
charchar
unsigned charunsigned char
charchar
bytebyte
N/AN/A
ByteByte
wchar_twchar_t wchar_twchar_t charchar IntegerInteger
ScriptScript
neinnein
jaja
neinnein
jaja
neinnein
neinnein
neinnein
neinnein
jaja
jaja
neinnein
jaja
neinnein
Wie funktioniert‘s?Datentypen
bytebyte
booleanboolean
VARIANT_BOOLVARIANT_BOOL
IDLIDL C++C++ JavaJava
BYTEBYTE
unsigned charunsigned char
longlong
VARIANT_BOOLVARIANT_BOOL
charchar
intint
booleanboolean
unsigned charunsigned char bytebyte
Visual BasicVisual Basic
N/AN/A
LongLong
BooleanBoolean
ByteByte
BSTRBSTR
VARIANTVARIANT
BSTRBSTR java.lang.Stringjava.lang.String
VARIANTVARIANT com.ms.com.Variantcom.ms.com.Variant
StringString
VariantVariant
CYCY longlong intint CurrencyCurrency
DATEDATE
enumenum
doubledouble doubledouble
enumenum intint
DateDate
EnumEnum
Typed ObjRefTyped ObjRef IFoo *IFoo * interface IFoointerface IFoo IFooIFoo
structstruct structstruct final classfinal class TypeType
unionunion
C-ArrayC-Array
unionunion N/AN/A
arrayarray arrayarray
N/AN/A
N/AN/A
ScriptScript
neinnein
neinnein
jaja
jaja
jaja
jaja
jaja
jaja
jaja
jaja
neinnein
neinnein
neinnein
Wie funktioniert‘s?Datentypen
Wie funktioniert‘s?COM-Schnittstellen, Tipps & Hinweise Visual Basic unterstützt nicht alle
Möglichkeiten der IDL
• Schnittstellen müssen immer von IDispatch abgeleitet sein
• Vererbung „eigener“ Schnittstellen ist nicht möglich
• Alle Methoden müssen ein HRESULT zurückgeben
• Parameter sollten keine „Unsigned Parameter“ (z.B. unsigned long) oder Zeiger sein
• Reine [out]-Parameter sind nicht erlaubt
Demo
OLE32.DLLOLE32.DLL
Service Control ManagerService Control Manager(RPCSS.EXE)(RPCSS.EXE)
carserver.dllcarserver.dll
Service Control Service Control ManagerManager
OLE32.DLLOLE32.DLL
carclient.execarclient.exe
OLE32.DLLOLE32.DLL
carclient.execarclient.exe
Wie funktioniert‘s?Der Service Control Manager (SCM)
VB-Runtime ruft CoCreateInstance auf und übergibt CLSID und IID an den SCM
SCM sucht anhand der CLSID den dazugehörigen COM-Server über Registry-Einträge und lädt ihn ggf. in den Speicher
COM-Server erstellt Instanz der Co-Klasse und erstellt anhand der IID eine Referenz auf die gewünschte Schnittstelle
Der SCM reicht die Referenz an den Client weiter
Der SCM „verlässt die Bühne“
Wie funktioniert‘s?Anlegen eines COM-Objekts
HKEY_CLASSES_ROOT
CFord
{CLSID_CFord}
@=CFord
Wie funktioniert‘s?
CLSID
InprocServer32
C:\CarServer.dll
ProgID
@=CFord
CLSID
@={CLSID_CFord}
New
• Objekt wird direkt auf Basis der CLSID erzeugt
CreateObject
• ProgID wird in CLSID umgewandelt
• Objekt wird auf Basis der CLSID erzeugt
Wie funktioniert‘s?New und CreateObject
Sie können Ihre Anwendung noch weiter Entkoppeln
• Erstellen Sie Objekte nicht direkt
• Delegieren Sie diese Aufgabe an ein eigens dafür entwickeltes Objekt
• Solche Objekte nennt man auch Class Factory
• Ihre Anwendung braucht dann nur die Schnittstelle und das „Factory Objekt“ zu kennen
Wie funktioniert‘s?Was ist eine ClassFactory?
Demo
In-Process• VB ActiveX DLL-Projekt
• läuft gleichen Adressraum wie der Aufrufer
Out of Process• ActiveX EXE-Projekt
• läuft im eigenen Prozess
• läuft auf der selben Maschine wie der Aufrufer
Remote• ActiveX EXE-Projekt
• läuft in eigenem Prozess
• läuft auf einer anderen Maschine
Wie funktioniert‘s?COM-Server
Achten Sie darauf, das bei den Projekteigenschaften die Einstellung „Binärkompatibilität“ gewählt ist• Beim aller ersten Übersetzen „No
Compatibility“ Bei unterschiedlichen Adressräumen
müssen Schnittstellenreferenzen transferiert werden
Diesen Vorgang nennt man Marshalling• Erfolgt mit sogenannten Proxy-Stub-DLLs
• ist im Bezug auf die Performance teuer
Wie funktioniert‘s?COM-Server
Unter Visual Basic werden nur STA-Threads benutzt• Sämtliche Objektzugriffe werden von COM
synchonisiert ActiveX EXE
• Thead per Object: Jede Instanz läuft in eigenem Thread
• Thread Pool: Alle Instanzen müssen sich Threads teilen und der SCM (RPCSS.EXE) sorgt für die „Verwaltung der Threads“
ActiveX DLL• Single Theaded: Alle Instanzen laufen in ein und dem
selben Thread ( sinnvoll für Singletons)
• Apartment Threaded: Alle Objekte eines Clients laufen im gleichen Thread
Wie funktioniert‘s?Threading
Demo
OLEAUT32.DLL enthält den Universal Marshaller, der das Marshalling auf Basis der TypeLibrary durchführen kann
Die Schnittstellen in der TypeLibrary müssen das Attribut dual oder or oleautomation aufweisen
Die TypeLib muss auf Client UND Server registriert werden ( CliReg32)
Methodenparameter müssen “VARIANT-compliant” sein
Wie funktioniert‘s?Universal Marshaller
HKEY_CLASSES_ROOTHKEY_CLASSES_ROOT
CLSIDCLSID
@=PSOAInterface@=PSOAInterface
InprocServer32InprocServer32
@=oleaut32.dll@=oleaut32.dll
@=IPager@=IPager
ProxyStubClsid32ProxyStubClsid32
@={CLSID_UniMarsh}@={CLSID_UniMarsh}
{IID_IPager}{IID_IPager}{CLSID_UniMarsh}{CLSID_UniMarsh}
InterfaceInterface
@=IMessageSource@=IMessageSource
ProxyStubClsid32ProxyStubClsid32
@={CLSID_UniMarsh}@={CLSID_UniMarsh}
{IID_IMessageSource}{IID_IMessageSource}
ThreadingModel=bothThreadingModel=both
TypeLibTypeLib
Wie funktioniert‘s?Universal Marshaller und die Registry
Demo
Benutzen Sie bei Aufrufen über das Netz nach Möglichkeit keine Properties • Pro Property ein Roundtrip
Seit DCOM 1.2 können UDTs mit dem Universal Marshaller übertragen werden• Windows 95: DCOM 1.2 installieren
• in NT4 ab Service Pack 4
• in Windows 98 und 2000 eingebaut VB arbeitet ausschließlich mit dem
Universal Marshaller• Ausnahme: ADO-Recordset
Wie funktioniert‘s?DCOM: Allgemeine Tipps
ByRef bedeutet, dass ein Parameter in beide Richtungen wird• IDL-Attribute [in, out]
• Achtung: wird von VB standardmäßig benutzt
• „2 Roundtrips notwendig!“ ByVal bedeutet, dass ein Parameter in
eine Richtung übertragen wird• IDL-Attribute [in]
Reine „Out-Parameter“ werden von VB nicht unterstützt
Wie funktioniert‘s?DCOM: ByRef und ByVal
Objekte können standardmäßig nicht über das Netz transportiert werden
• Custom-Marshalling in VB nicht möglich• Schnittstelle IMarshal für jeweiliges Objekt mit
Visual C++ implementieren
• Ausnahme: ADO-Recordsets
Entwickeln Sie „Pseudo-Proxy/Stubs“
• sinnvoll, wenn Sie bspw. mit Collections arbeiten
Wie funktioniert‘s?DCOM: Objekte
Demo
Aufzählungen müssen sich immer in einem Klassenmodul befinden
Benutzen Sie immer die Einstellung „Binär-kompatibel“
• Der Rest macht nur Ärger und „müllt“ die Registry zu
Für Klassen werden Standardschnitt-stellen erstellt
• Eigene Schnittstellen per implements
• Erstellen Sie die IDL mit Visual C++
Wie funktioniert‘s?Tipps & Hinweise
msdn• www.microsoft.com/germany/msdn
• www.microsoft.com/germany/msdn/quickie
TechTalk• www.microsoft.com/germany/msdn/techtalk
• microsoft.public.de.german.entwickler.techtalk
Sites
• www.wrox.com ( Büchersuche)
Wo gibt’s weitere Info’s?Online
Bücher
• Programming Distributed Applications...Ted PattisonISBN 1-57231-961-5Microsoft Press
• COM IDL and Interface DesignISBN 1-86100-235-4Wrox Press
Zeitschriften
• basicpro
• Microsoft System Journal, 6/99, Seite 85
Wo gibt’s weitere Info’s?Online
Fragen!?
Uff...Uff...