Als fleißiger Komponenten-Entwickler sind Sie wahrscheinlich
auch hin und wieder über recht seltsam anmutende
Inkompatibilitäten gestolpert. Sie bereinigen beispielsweise einige
Bugs in einer COM-Komponente und lassen die Schnittstelle auch ganz
brav unverändert. Ihrem guten Gewissen Hohn sprechend meldet sich
dennoch beim Erstellen des Projekts der gefürchtete Dialog, der
Ihnen weismachen will, dass die Schnittstelle nicht mehr
binärkompatibel zur Vergleichsdatei sei:
<Prozedur> im Klassenmodul <Klassenmodul> hat eine Prozedur-ID,
die von einer ähnlichen Deklaration in der versionskompatiblen
Komponente abweicht.
Lassen Sie sich daraufhin die angeblich inkompatible Deklaration
anzeigen, bekommen Sie beispielsweise folgendes zu lesen:
Die Deklaration in der kompatiblen ActiveX-Komponente war:
Property Get Eigenschaft1() As String
Sie wurde geändert in:
Property Get Eigenschaft1() As String
Auf den ersten Blick gibt es hier eigentlich nichts zu
beanstanden, denn Name und Parameter der Eigenschaft haben sich
nicht geändert, und die Rückgabe erfolgt immer noch mit dem
gleichem Datentyp.
Sie provozieren diesen Fehler, wenn Sie eine Klasse (oder ein
UserControl) mit öffentlichen, schreibgeschützten, aber intern zu
schreibenden Eigenschaften versehen (Public Property Get/Friend
Property Let). Diese Konstellation löst allein jedoch
noch keine Inkompatibilitätsfehler aus. Erst wenn Sie diese
Eigenschaften mit Prozedurattributen versehen (Menü Extras/Prozedurattribute),
etwa mit einer Prozedurbeschreibung oder mit der bemängelten
Prozedur-ID, erhalten Sie beim Erstellen der binärkompatiblen
Komponente oben stehende Fehlermeldung.
Dabei spielt die Reihenfolge der Prozeduren eine große Rolle.
Arbeiten Sie in der Prozeduransicht, stellt die VB-IDE eine Property
Let-Prozedur generell vor eine Property Get-Prozedur,
egal in welcher Reihenfolge diese eingegeben wurden.
Friend Property Let Eigenschaft1(New_Value As String)
' ...
End Property
Friend Property Get Eigenschaft1() As String
' ...
End Property
Legt Sie nun in den Prozedurattributen die Beschreibung der
Prozedur fest, wird diese Beschreibung in der Code-Datei unter die
Friend-Prozedur geschrieben. Öffnen Sie diese Code-Datei (etwa im
Editor/Notepad), bekommen Sie folgendes zu sehen:
Friend Property Let Eigenschaft1(New_Value As String)
Attribute Eigenschaft1.VB_Description = "Beschreibung"
'...
End Property
Public Property Get Eigenschaft1() As String
' ...
End Property
Eine Friend-Prozedur wird jedoch nicht als externe Schnittstelle
betrachtet, sondern steht nur innerhalb des Projekts zur Verfügung.
Der Compiler bemängelt an dieser Stelle auch noch keinen Fehler und
nimmt die Prozedurbeschreibung korrekt in das Kompilat auf.
Der Fehler tritt erst dann auf, wenn Sie eine binärkompatible
DLL erstellen wollen. Logisch lässt sich diese Fehlermeldung
allerdings nicht erklären, da die Prozedurbeschreibung der
Binärkompatibilität in der Regel nicht im Wege steht. Die
Prozedurbeschreibung können Sie durchaus beliebig festlegen und
auch wieder löschen, ohne Verlust der Binärkompatibilität.
Obwohl sie nicht festgelegt wurde, wird die auch die Prozedur-ID
in der Fehlermeldung bemängelt. Hier wäre dieses Fehlverhalten
eher gerechtfertigt, da eine Änderung der Prozedur-ID den Charakter
der Prozedur ändern würde und damit die Schnittstelle inkompatibel
wäre.
Dies spielt aber eigentlich gar keine Rolle, da der Fehler
maßgeblich durch die Festlegung der Prozedurattribute ausgelöst
wird und erst beim Kompilieren zu Tragen kommt. Beim Zuweisen der
Attribute wird nämlich nur die erst passende Prozedur gewählt,
unter Missachtung des Schlüsselworts Friend. Und so passiert es
dann, dass die Attribute an der falschen Stelle in für die an sich
öffentliche Prozedur geschrieben werden.
Verschieben Sie nun die Prozedurbeschreibung mit Hilfe des
Editors in die tatsächliche, öffentliche Prozedur, haben sich die
Probleme verflüchtigt:
Friend Property Let Eigenschaft1(New_Value As String)
' ...
End Property
Public Property Get Eigenschaft1() As String
Attribute Eigenschaft1.VB_Description = "Beschreibung"
' ...
End Property
Allerdings können Sie auf diese Weise die Binärkompatibilität
zu einer bestehenden Komponente nicht wahren. Darum sollten Sie das
Problem von vornherein umgehen und auf die Reihenfolge solcher
Prozeduren in der Modul-Ansicht achten. Schreiben Sie also zuerst
die öffentliche Prozedur und lassen Sie die internen nachfolgen.
Dann werden die Prozedurattribute auch ohne externe Nachhilfe mit
einem Editor an die richtige Stelle geschrieben:
Public Property Get Eigenschaft1() As String
Attribute Eigenschaft1.VB_Description = "Beschreibung"
' ...
End Property
Friend Property Let Eigenschaft1(New_Value As String)
' ...
End Property
|