Vor- und Nachteile der Verwendung von DLLs [geschlossen]

7

Ich frage mich, ob ich jedes Game-Engine-Modul (Rendering, Eingabe, Sound usw.) in DLLs (renderer.dll, input.dll usw.) erstellen soll. Was sind Ihrer Meinung nach Vor- und Nachteile einer Aufteilung des Spiels in DLLs? Ich sehe nur die Notwendigkeit, das Spielmodul in eine separate DLL zu schreiben, um die Möglichkeit zu haben, Mods zu erstellen.

Piotrek
quelle
1
Vor- und Nachteile im Vergleich zu einer statischen Bibliothek oder zu keiner Bibliothek?
Maik Semder

Antworten:

4

Vorteile

  • Sie können DLLs separat erstellen.
  • Es könnte schneller sein, eine DLL neu zu erstellen

Nachteile

  • Das Aufrufen von Code aus der DLL ist langsamer
  • Es wäre langsamer, ein Lochprojekt mit allen DLLs neu zu erstellen
  • Funktionsnamen sind sichtbar. Es ist einfacher, Code umzukehren, der dynamische DLLs verwendet

Ich sehe keinen Sinn darin, render.dll und input.dll zu haben. Aber einige RareUsedJoystick.DLL könnten als ladbares Modul erstellt werden, um Speicher für diejenigen freizugeben, die diesen RareUsedJoystick nicht verwenden

Max
quelle
1
Haben Sie Quellen dazu? Aus meinem Verständnis und meiner Erfahrung mit dem Kompilieren und Verknüpfen würde ich nichts sagen, aber der letzte Punkt ist wahr.
API-Beast
1
In großen Projekten ist das Verknüpfen viel schneller, wenn Sie DLLs verwenden. Beachten Sie auch, dass es schwieriger ist, komplexe Typen in einer DLL zu debuggen.
Jonathan Connell
1
Statische Verknüpfungen können Inline-Funktionen enthalten. Es ist nicht möglich, die DLL-Funktion zu integrieren, da sich die DLL in Zukunft möglicherweise ändern wird. Dies ist auch ein Grund, warum die DLL-Verknüpfung schneller ist. Ich sagte, es wäre langsamer, alle DLLs separat zu kompilieren, als den gesamten Code in einer einzigen EXE zu kompilieren
Max
1
Der Compiler / Linker kann bei statischer Verknüpfung besser optimieren. Dies bedeutet jedoch nicht, dass das Aufrufen von Funktionen im Allgemeinen langsamer ist.
API-Beast
Die Funktion in der Bibliothek für dynamische Verbindungen wird als langsamer bezeichnet. Weil Ihre Code-Aufrufe nach Index im Array funktionieren. Es sind zusätzliche 1-3 Operationen, aber viele Funktionen sind nur Getter / Setter, die selbst 1-3 Operationen sind. Bei statischer Verknüpfung und Inlining könnte es 1 CPU op. Ohne Inlining könnte die statische Bibliothek Register verwenden, um Funktionsargumente zu übergeben. Im Falle von DLL. Es verwendet Stack, um Argumente zu übergeben. Es nimmt die Funktionsadresse nach Index im Array an. Es gibt viele zusätzliche Operationen, die durch statische Verknüpfungen entfernt werden.
Max
3

Das Einfügen von Code in separate Windows-DLLs klingt theoretisch vielversprechend, in der Praxis sollten Sie sich jedoch bestimmter Einschränkungen bewusst sein.

  1. Sie müssen alle Ihre Klassen und globalen Funktionen, die Sie von außen verwenden möchten, als "exportierbar" deklarieren

    __declspec( dllexport ) class Foo {};

    beim Aufbau der Bibliothek. Clients Ihrer DLL müssen das Include wie folgt "sehen":

    __declspec( dllimport ) class Foo {};

    Aus diesem Grund sehen Sie ein Makro vor Klassendeklarationen in DLL-Headern.

  2. Ressourcen wie FILE * -Zeiger können nicht unter allen Umständen (verschiedene CRTs) zwischen DLLs gemeinsam genutzt werden. Das heißt, wenn Sie die Datei in einer DLL öffnen, können Sie weder über die Client-App oder eine andere DLL darauf schreiben noch sie schließen.

    http://msdn.microsoft.com/en-us/library/ms235460%28VS.80%29.aspx

  3. Speicherverwaltung: Sie können unter allen Umständen keinen Speicher in der DLL zuweisen und in einer anderen DLL oder in einer Clientanwendung freigeben (unterschiedliche CRTs).

  4. Das Exportieren von Vorlagenklassen kann sehr schmerzhaft sein, insbesondere wenn statische Elementvariablen verwendet werden.

Wenn Sie Ihren Code nur wiederverwenden möchten, ohne ihn neu zu kompilieren, gibt es eine andere Option, statische Bibliotheken (.lib). Es handelt sich um vorkompilierten Code (wie in der DLL), der jedoch mit Ihrer Anwendung verknüpft ist und keine der oben genannten Einschränkungen aufweist. Außerdem funktioniert die Generierung des Link-Zeitcodes weiterhin mit dem Bibliothekscode.


Update: Wie Sean in den Kommentaren hervorhob, können Punkt 2 und 3 funktionieren, wenn dieselbe CRT-Version verwendet wird, wie auch der MSDN-Link in 2 zeigt. Mein Rat ist jedoch, die DLL zu entwerfen, ohne sich darauf zu verlassen, da es so viele Fälle gibt, in denen sie nicht funktioniert, z. B. die Verwendung von 2 DLLs mit unterschiedlichen CRTs oder die Kompilierung mit unterschiedlichen Visual Studio-Versionen.

Maik Semder
quelle
Die Speicher- und FILE * -Ansprüche (2 und 3) sind nicht ganz richtig. Diese Probleme treten auf, wenn die DLL eine andere CRT-Version verwendet. Wenn mit der App selbst erstellt, ist dies kein Problem.
Sean Middleditch
@ Sean richtig, theoretisch. In der Praxis gibt es viele Fälle, in denen dies nicht funktioniert (siehe MSDN-Link), z. B. DLLs aus verschiedenen VS-Versionen, die mit 2 DLLs mit unterschiedlichen CRTs verknüpft sind. Daher ist es sicherer, die DLL so zu gestalten, dass Sie sich nicht darauf verlassen. Dies ist eine wichtige Einschränkung, die Sie beachten sollten. Sie sollte hier aufgeführt werden. Ich habe jedoch ein Update in meine Antwort
eingefügt, das
Ich würde behaupten, es ist nicht "nur Theorie". Sicher, wenn Sie DLLs als eigenständige Komponenten entwerfen, ist dies ein Problem. Bei der ursprünglichen Frage geht es darum, nur eine einzelne App in DLLs aufzuteilen. Dies bedeutet, dass die DLLs gleichzeitig mit demselben Compiler erstellt werden. Dies ist in Game-Engines aus einer Vielzahl von Gründen tatsächlich etwas üblich (z. B. Laden verschiedener optimierter Codeversionen für verschiedene CPU-Befehlssatzvarianten), und in diesen Fällen ist es in der Praxis absolut sicher anzunehmen, dass diese Probleme nicht auftreten. :)
Sean Middleditch
Es ist auch zu beachten, dass dies nur gilt, wenn Sie MSVC verwenden. GCC (MinGW) exportiert standardmäßig alles.
API-Beast
@ Mr.Beast Wäre das Export oder Import? Ich benutze selbst MinGW. War aber ziemlich verwirrt über die Standardeinstellungen für DLLs.
Sidar
1

Die meisten Unterschiede sind vernachlässigbar. DLLs sind flexibler, machen den Erstellungsprozess jedoch komplexer. Ich würde DLLs nur verwenden, wenn:

  • Mehrere Anwendungen müssen auf dieselbe Funktionalität zugreifen. Zum Beispiel, wenn Sie separate Binärdateien für einen Editor und das Spiel selbst haben.
  • Sie möchten, dass Sie oder andere Personen bestimmte Komponenten ersetzen können. In Civ IV könnten Modder beispielsweise Ersatz für die DLLs des Spiels liefern, um Teile des Gameplays grundlegend zu ändern.
  • Sie möchten sie zur Laufzeit laden, um die Anwendung um Plugins von Drittanbietern erweitern zu können.
API-Beast
quelle
0

Ein weiterer Vorteil ist, dass Sie damit Ihren Code richtig strukturieren können. Nicht logische Abhängigkeiten zwischen Modulen werden stärker hervorgehoben und es wird schwieriger, solche Hacks zu verwenden.

Tomas Andrle
quelle