Das Thema richtet sich primär an Carsten, der ja die Schnittstellen der DLLs festlegt.
- Der Name von Methoden muss eindeutig sein. Methoden dürfen nicht wie in vielen Programmiersprachen üblich überladen sein, d.h. sich nur in den Parametern unterscheiden.
- Die Signatur von Methoden sollte sich natürlich nicht ändern. Das heißt, es muss Reihenfolge, Anzahl und Datentyp der Parameter gleich sein, es darf sich aber z.B. der Wertebereich ändern.
- Dies sollte auch DLL-Übergreifend der Fall sein. Das heißt, es ist schlecht, wenn eine DLL eine Init mit einem Parameter hat, und die andere mit null Paramtern.
- Wenn das nicht beachtet wird, ist das bei x64 trotzdem kein Problem. Wenn eine Funktion einen Parameter mehr bekommt, können alte DLLs weiterhin mit dem neuen Zusi laufen und neue DLLs laufen mit dem alten Zusi, sofern sie nicht auf den Paramter zugreifen. Wenn sie doch zugreifen, bekommen sie bei Zahlen Müll, bei Pointern stürzen sie ab.
- Bei x86 (32 bit) ist bei __stdcall aber (frei nach Alwin) Tag des Kotzenden Einhorns und der Programmierer hat den Hauptpreis gewonnen und muss die Größe des zu bereinigenden Stacks von Hand in Assembler festlegen. Zusi könnte da zwar vermutlich auch selbst aufpassen, aber vermutlich wird auch das Eingriffe in Assembler erfordern. Also einfachste Lösung: 32bit aufgeben, oder einfach unterschiedliche Namen verwenden.
- Der Standard-Name für Funktionen, die geänderte Parameter bekommen haben, lautet unter Windows "Blub" -> "BlubEx" (Extension) -> "BlubEx2" -> ...
- Wenn Zusi die alten DLLs unterstützen will, kann Zusi prüfen, ob eine "BlubEx" existiert und wenn nicht die "Blub" aufrufen.
- Übergabe von Strukturen von Zusi an eine DLL:
- Grundsätzlich gilt: Die Reihenfolge der Felder in einer Struktur darf nicht geändert werden. Das heißt neue Felder müssen immer ganz unten dazu geschrieben werden. Edit: Es dürfen keine Felder gelöscht werden. Sie müssen gegen ein anderes Feld vom selben Datentyp (oder Datentyp der selben Größe) ersetzt werden oder gegen ein Platzhalter-Feld "Reserviert" ersetzt werden, das an der selben Position in der Reihenfolge stehen muss.
- Werden zusätzliche Felder in die Struktur eingefügt, muss man nicht zwingend eine neue Methode aufmachen. Man muss aber dafür ein paar Vorarbeiten getroffen haben:
- Option 1: Man macht einfach ein paar "Reserviert: Immer 0"-Felder ans Ende der Struktur (oder auch zwischen rein). Die DLL greift auf diesen Wert dann einfach nicht zu, man kann den Datentyp dann nachher weitgehend beliebig ändern, solange er gleich groß ist.
- Option 2: Man macht als erstes Feld in der Structure ein Feld, in dem die Größe der Struktur angegeben ist. Also sitz_t size = sizeof(Structure); Einige Windows-Messages haben so ein Vorgehen. Die DLL kann dann anhand dieses Größen-Feldes unterscheiden, ob es auf die neu hinzugekommenen Felder zugreifen darf oder nicht. Alte DLLs würden weiterhin funktionieren, neue könnten bewusst feststellen, was sie gerade machen wollen. Edit: Zudem müssen die Strukturen als var übergeben werden, ansonsten geht die 32-Bit-Verison nicht.
- Option 3: Man macht gar keine Vorbereitungen. Wenn man die Reihenfolge der Felder in der Struktur nicht ändert und neue Felder immer ganz ans Ende schreibt, funktionieren unter allen Prozessor-Architekturen die alten DLLs weiterhin. Neue DLLs sind dann unproblematisch, wenn sie nicht auf die neuen Felder zugreifen. Wenn sie doch auf die neuen Felder zugreifen, aber mit dem alten Zusi betrieben werden, stürzt Zusi ab. Das wäre aber in meinen Augen trotzdem ein verkraftbarer Sonderfall. Edit: Zudem müssen die Strukturen als var übergeben werden, ansonsten geht die 32-Bit-Verison nicht.
- Im Notfall kann man dann noch eine neue Methode aufmachen, aber in meinen Augen ist das nicht nötig. Ich denke, Option 2 wäre die einfachste.