Forum: PC-Programmierung DLL: jedes mal neue Instanz möglich?


von DLLcoder (Gast)


Lesenswert?

Hallo,

ich möchte eine dll erstellen (c++), die in ihrem Speicherbereich auch 
Daten/Objekte besitzt also nicht nur Funktionen beinhaltet.
Nach meiner Kenntnis verhält sich eine dll naturgemäß ein bisschen so 
wie „shared memory“ und wird normal nur 1x in den Speicher geladen, 
nutzen dann mehrere Threads/Prozesse die gleiche dll wird immer auf den 
selben Speicherbereich zugegriffen das heißt ohne Synchronisierung der 
Daten innerhalb der dll knallt es.

Ziel ist bei mir aber, dass jedes Programm welche die dll einbindet ein 
eigenen Speicherbereich der Daten der dll bekommt. Sozusagen so als 
würde die dll von jedem Programm neu in einen eigenen Speicherbereich 
geladen werden. Nach allem was ich bisher wusste geht das nicht.

Jetzt allerdings habe ich diese Aussage bei wiki gefunden: 
https://de.wikipedia.org/wiki/Dynamic_Link_Library#DLLs_im_Speicher
Zitat:
1
Es gibt zwei verschiedene Varianten, wie DLLs vom Betriebssystem in den Speicher geladen werden können. Es gibt statische DLLs, die nur einmal geladen werden. Alle Programme greifen dann auf diese eine Instanz der DLL zu. Diese DLL besitzt dann nur einen einzigen globalen Speicherbereich. Die Windows-Kernel-DLLs sind solche statischen DLLs, was ihnen erlaubt, das gesamte System zu verwalten (z. B. alle offenen Dateien zu überwachen). Eine andere Variante DLLs im Speicher zu verwalten, ist die, dass jedes Mal, wenn ein neues Programm eine DLL benötigt, eine neue Instanz von dieser in den Speicher geladen wird. 
2
Ob eine DLL statisch ist oder nicht, legt ein weiteres Flag im Header der DLL fest.

Die Aussage „...jedes Mal, wenn ein neues Programm eine DLL benötigt, 
eine neue Instanz von dieser in den Speicher geladen wird.“ klingt für 
mich nach dem was ich suche, als wäre es doch möglich eine dll zu 
erstellen die von jedem Programm neu in den Speicher geladen wird. 
Funktioniert das wirklich und was muss dann genau in dem Flag des 
Headers stehen damit die dll jedes mal neu in den Speicher geladen wird? 
Leider konnte ich dazu nirgendwo etwas finden.

Grüße

von Dr. Sommer (Gast)


Lesenswert?

Mach doch einfach eine Funktion, welche vom die DLL nutzenden Programm 
aufgerufen wird, per malloc() den benötigten Speicher anfordert und 
einen Pointer darauf an das Programm zurückliefert. Genau so, wie man C 
Module sinnvollerweise strukturiert.

von georg (Gast)


Lesenswert?

DLLcoder schrieb:
> wird normal nur 1x in den Speicher geladen,
> nutzen dann mehrere Threads/Prozesse die gleiche dll wird immer auf den
> selben Speicherbereich zugegriffen

Ja, Nein. Der Code der DLL wird nur einmal geladen, die Speicherbereiche 
sind getrennt.

https://docs.microsoft.com/en-us/windows/desktop/dlls/about-dynamic-link-libraries

Georg

von Oliver S. (oliverso)


Lesenswert?

Da oben auch das Stichwort "Thread" fiel, könnte das hier auch noch 
hilfreich sein:

https://docs.microsoft.com/en-us/windows/desktop/dlls/using-thread-local-storage-in-a-dynamic-link-library

Oliver

von DLLcoder (Gast)


Lesenswert?

Danke super, das Stichwort zur Lösung ist wohl "Thread-local storage" um 
jedem Thread eigene Variablen zu verschaffen.

Ich werde mal die C++11 Variante ausprobieren: 
https://en.cppreference.com/w/cpp/language/storage_duration

#include <thread>
thread_local int number;

Ansonsten gibts wohl noch compilerabhängige Dinge wie
__declspec(thread) int number;
oder
__thread int number;

Mal sehen wie das klappt :)

LG

von Dr. Sommer (Gast)


Lesenswert?

DLLcoder schrieb:
> Danke super, das Stichwort zur Lösung ist wohl "Thread-local storage" um
> jedem Thread eigene Variablen zu verschaffen.

Und du bist sicher, dass man aus einem Thread niemals nie 2 Datensätze 
anlegen möchte? Oder nie von 2 Threads auf die selben Daten zugreifen? 
Oder die Daten zwischen 2 Threads tauschen?

Was sind das denn für Daten, und was haben die mit Threads zu tun? Wenn 
das eine gewöhnliche Datenstruktur ist, ala "3D-Modell" oder "Datei in 
meinem Spezial-Format" oder "Verbindung mit einem Gerät", kann es 
durchaus passieren dass man irgendwann mal aus 1 Anwendung oder 1 Thread 
mehrere davon haben will. Für so einen Fall ist es viel besser, wenn die 
Anwendung die Datenstruktur explizit anlegen kann. Dazu bietest du z.B. 
eine Funktion "struct My3DModel* newModel(void);", in welcher du die 
Daten per malloc() anlegst. Den zurück gelieferten Pointer muss die 
Anwendung dann an jede weitere Funktion übergeben. So wird der Zugriff 
auf die Daten deutlich transparenter und flexibler, es ist dem Nutzer 
immer ersichtlich welche Datensätze gerade existieren. Das ist so das 
übliche Vorgehen. Bei Thread Local Storage wird das versteckt und kann 
nicht beeinflusst werden. Du zwingst so der Anwendung eine bestimmte 
Struktur auf. Sollte irgendwann mal wer auf die Idee kommen die DLL aus 
einer Script Sprache wie Ruby oder Python heraus zu nutzen, kann er nur 
1 Datensatz anlegen, da diese Sprachen keine echten Threads haben - 
mies!

von DLLcoder (Gast)


Lesenswert?

Ja stimmt schon, ist auf jeden Fall flexibler und lässt mehr Freiheiten 
per dynamischer Speicherverwaltung

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.