6 Stimmen

Gemeinsam genutzte globale Variable in der statischen C++-Bibliothek

Ich habe ein MS C++-Projekt (nennen wir es Projekt A), das ich derzeit als statische Bibliothek (.lib) kompiliere. Es definiert eine globale Variable foo. Ich habe zwei andere Projekte, die separat kompiliert werden (nennen wir sie B bzw. C) und jeweils die gemeinsame statische Bibliothek A einbinden. Sowohl B als auch C sind dlls, die am Ende im selben Prozess geladen werden. Ich möchte eine einzelne Instanz von foo aus A zwischen B und C im selben Prozess teilen: ein Singleton. Ich bin mir nicht sicher, wie ich das Singleton-Muster hier mit Projekt A erreichen kann, da es statisch in B und C separat kompiliert wird. Wenn ich foo sowohl in B als auch in C als extern deklariere, erhalte ich unterschiedliche Instanzen in B und C. Die Verwendung eines standardmäßigen, einfachen Singleton-Klassenmusters mit einer statischen getInstance-Methode führt zu zwei statischen foo-Instanziierungen.

Gibt es eine Möglichkeit, dies zu erreichen, während Projekt A statisch in B und C kompiliert wird? Oder muss ich A zu einer DLL machen?

4voto

Jeremy Bell Punkte 5123

Ja, Sie müssen A zu einer gemeinsam genutzten DLL machen, oder sie als extern in B und C definieren und alle drei statisch verknüpfen.

2voto

Ragster Punkte 719

Nein - sie werden nicht geteilt.

Aus Richters 'Windows via C/C++' (S. 583):

Wenn ein Prozess eine DLL abbildet in seinen Adressraum abbildet, wird die s und der statischen Datenvariablen.

Wenn Sie also eine Ressource für mehrere ausführbare Programme freigeben wollen, müssen Sie eine Art gemeinsames Kernelobjekt erstellen. Ich würde vorschlagen, eine benannte Dateizuordnung zu erstellen, die Sie dann zum Lesen und Schreiben von den einzelnen Prozessen aus verwenden können (natürlich mit entsprechendem Mutex-Ausschluss).

0voto

user7098596 Punkte 1

Ich habe dieses Problem tatsächlich:

Ich habe A.EXE mit B.LIB verknüpft. Ich habe C.DLL auch mit B.LIB verknüpft.

Wie Sie sehen können, sind diese beiden Programme mit B.LIB verbunden

Bei Bedarf lädt die A.exe nun die C.DLL. Nach dem Laden haben A.EXE und C.DLL jeweils eine eigene B.LIB für Code und Daten

Das Problem ist es möglich, eine B.LIB "fantom" mit C.DLL verknüpft haben, um die bereits in A.exe geladen verwenden?

Ich denke nein. Das ist eine Einschränkung von Windows. Unter Linux kann man das, wenn ich mich richtig erinnere. Das wurde von der Option -fPic des GCC so gesehen. Aber nicht sicher.

Die Lösung für die gemeinsame Nutzung von globalen/statischen Daten, die in B.LIB gespeichert sind, mit A.EXE und C.DLL ist die Verwendung von gemeinsamen Klassen/Schnittstellen. Ihre A.EXE sendet eine Schnittstelle zu C.DLL mit einem Daten-/Schnittstellenzeiger auf die in A.EXE gespeicherte B.LIB.

Mit anderen Worten, wenn Ihre C.DLL den Status einer statischen Variable in B.LIB setzen/freigeben muss, muss Ihre A.EXE C.DLL mit der Schnittstelle initialisieren, um den Datenaustausch mit der B.LIB in A.EXE zu ermöglichen.

In allen Fällen bläht die in C.DLL gespeicherte B.LIB das globale Programm aufgrund des doppelten Codes von B.LIB in A.EXE und C.DLL weiter auf.

Um die globale Aufblähung zu reduzieren, müssen Sie Ihre A.LIB in mehrere D.DLL und E.DLL aufteilen, die von A.EXE geladen und über die Schnittstelle an Ihre C.DLL übertragen werden.

Um den aufgeblähten Code auf Null zu reduzieren, müssen Sie eine vollständig unabhängige Schnittstellenmethode verwenden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X