Sonntag, Dezember 15, 2019

Kann ich pass std::string um eine DLL?

Trennte ich ein code-fragment in einen DLL denn es wird Häufig aktualisiert, und auf diese Weise sollte es leichter sein, zu implementieren.

Aber ich habe Fragen über das, was ich tun kann und was ich nicht tun kann, mit einem DLL.

  1. Kann ich passiere ein std:string oder eine CString zu einem DLL?
  2. Kann ich übergeben Sie einen Zeiger auf eine struct mit std::string members und füllen Sie es in eine DLL?
  3. Kann ein DLL gibt einen Zeiger auf ein struct zugewiesen, die es gibt? Wird es gültig? Kann ich es löschen nach?
  4. Was sollte besser zu pass, ein std::String oder eine Cstring?

Dank !

InformationsquelleAutor bratao | 2011-03-18

2 Kommentare

  1. 23

    Haben Sie eine Wahl zu machen:

    • Eng gekoppelt DLL: Die DLL ist gebaut mit den gleichen compiler-version, die Verpackung und die Aufrufkonvention Einstellungen, Bibliothek-Optionen, wie die Anwendung, und beide dynamisch zu verknüpfen, um die Laufzeit-Bibliothek (/MD compiler-option). Dadurch können Sie Objekte übergeben hin und her, einschließlich STL-Containern zuordnen DLL-Objekte, die aus der Anwendung heraus, ableiten von Basisklassen in das andere Modul, einfach über alles, was Sie konnte, ohne die Verwendung von DLLs. Der Nachteil ist, dass Sie nicht mehr bereitstellen der DLL unabhängig von der Hauptanwendung. Beides muss gebaut werden, zusammen. Die DLL ist nur zu verbessern, Ihre Prozess-Start-Zeit und die Arbeit eingestellt, weil die Anwendung gestartet werden kann, läuft vor dem laden der DLL (Verwendung der /delayload linker-option). Die Bauzeiten sind auch schneller als ein single-Modul, vor allem, wenn ganze Programm-Optimierung verwendet wird. Aber die Optimierung erfolgt nicht über die Anwendung-DLL-Grenze. Und jede nicht-triviale ändern, benötigen aber noch den Wiederaufbau sowohl.

    • Lose gekoppelt: Die Anwendung hängt nicht von der Klasse layout von Objekten definiert, die von der DLL. Verwenden Sie nur hoch kompatible Datentypen: einfache Typen, Zeiger, Funktionszeiger, und benutzerdefinierte Typen, der aus diesen Elementen. Klassen Erben von einer Basisklasse definiert Schnittstelle und hat keine Daten-member und nicht-virtuelle Funktionen (dies bedeutet keine Konstruktoren und keine Freigabe der standard-Bibliothek Objekte wie std::string oder CString). Alle Vergabe-und Objekt-Erzeugung erfolgt durch eine factory-Funktion. Speicher werden freigegeben, aus dem Modul, welches ihm zugeteilt. Code und Daten sind getrennt. Die header-Datei explizit fest, die Aufrufkonvention der jede exportierte Funktion und Verpackung jeder Struktur erlaubt modulgrenzen kreuzen. Der Vorteil ist, dass die DLL und die Anwendung aktualisiert werden kann, völlig unabhängig. Sie können neu erstellen mit neuem Laufzeit-Bibliothek, die neue compiler-version, oder sogar in einer ganz neuen Sprache, und nicht einmal berühren die anderen.

    Ich immer empfehlen die Verwendung der lose gekoppelten Ansatz.

    • Wow, schöne Erklärung.Ich wähle die Lose gekoppelt. Aber was ist „Alle Vergabe und Objekt-Erstellung erfolgt über eine factory-Funktion“ ? Ich kann die Verwendung der std in der dll-oder Atl-Funktionen ? Ich kann nicht löschen Sie einen Speicher in dll aus der Haupt-Anwendung ?
    • Sie löschen nicht zugeordneter Speicher in der DLL von der Hauptanwendung. Und die DLL benutzen können std::string, aber es ist anders als std::string in der Anwendung. Sie können nicht übergeben std::string zwischen Anwendung und DLL, die Sie anstatt pass char* wie Mark vorgeschlagen.
    • stimmt, ich fand die harte Art und Weise versucht, die Nutzung der Unreal Engine 4.7 + Boost + librabbitmq + SimpleAmqpClient zusammen, und ich kann auch nicht verbinden, weil die std::string URI beschädigt ist. Immer noch versuchen, herauszufinden, was ich nun tun soll…
    • Ich kam in dieser Frage. Aber vorbei std::string durch Verweis scheint zu funktionieren. Wird die übergabe std::string durch Verweis immer?Wie meine dll aussetzen Schnittstelle empfangen std::string &something und ich sollte in Ordnung sein?
    • Es wird nicht „immer“ funktionieren. Es ist fast garantiert, um auszufallen, wenn die Länge beeinflussen änderungen der std::string Objekt, aber wenn die compiler-und library-Versionen nicht übereinstimmen zwischen DLL und Anrufer, sogar nur-lese-Operationen kann fehlschlagen, schrecklich.
    • Wenn Sie sagen, „Zeiger“ in Ihrer Antwort, ist das auch std::unique_ptr & std::shared_ptr? Sind Sie sicher, um pass über die Grenzen hinweg? Oder nicht, weil Sie standard-Bibliothek-Typen?
    • Scoped-Ressource-management-Klassen sind NICHT sicher zu passieren, über die Grenzen hinweg. Sie können Sie verwenden, client-Seite für die Verwaltung der raw-Zeiger über die Grenze übergeben werden (stellen Sie sich ein custom deleter, dass Notrufe die richtige Freigabe-Funktion, die Standard-deleters funktioniert nicht in diesem Fall), aber die smart-pointer-Objekte nicht überschreiten können.
    • Vielen Dank für die Klarstellung! Das ist leider wirklich traurig.
    • Eine andere Sache, die ich nicht ganz verstehe: Microsoft bietet eine ABI-Kompatibilität garantieren zwischen allen Versionen von Visual Studio 2015 und 2017. Für mich bedeutet es wäre sicher zu verwenden std Arten in diesen Versionen? Und ähnlich ist es mit gcc – seine standard-Bibliothek ABI ist gehalten, mit einer stabilen ABI auch „getauft“ – mit Ausnahme von einigen seltenen Ausnahmen, wie die string Kuh ändern, das verursacht eine ABI-änderung. Natürlich ist dies alles nicht gewährleistet, die von den C++ – standard und es gibt keine offizielle ABI. Aber es ist ein de-facto-Garantie durch die einzelnen Anbieter. Wie wirkt sich das auf dein Antwort?
    • Man müsste schauen, Einzelheiten der Garantie, aber ich glaube nicht, es macht die situation deutlich besser. ABI-Kompatibilität bedeutet, dass wenn Ihre Aggregate von primitiven Typen ändern sich nicht definition, die man behandeln kann, diese speziellen compiler-Versionen als treffen der „exakt gleichen compiler-version“ – Anforderung. Aber Definitionen von Klassen in namespace std unterliegen immer noch ändern (müssen Sie, weil der C++ standards committee änderungen der Anforderungen), also diejenigen, die noch nicht verwendet werden modulübergreifend.
    • Es klingt wie Sie entschlossen sind, stoßen Ihr Glück-statt der Einführung eines Ansatzes, der ist robust. Selbst wenn Sie hatte insgesamt ABI-Kompatibilität und Bibliothek Invarianz zwischen bestimmten Versionen von dem gleichen Hersteller des Compilers, ich würde noch berücksichtigen, dass Sie eng gekoppelt sind, denn Sie nehmen die Wahl compiler von Verbrauchern in der DLL.
    • Hm.. Wie kommen OpenCV nimmt std::string& als argument in einige öffentliche Funktionen (imwrite, imread, cv::String ist ein typedef auf std::string)? Sie konnte nicht einfach verpassen

  2. 3

    Besteht die Gefahr bei der übergabe alles in und aus einer DLL, wenn es auf einer Vorlage basiert. Compiler-Optionen kann sich auf die Anordnung des Objekts und eine Vorlage-Klasse nicht beschränkt auf eine einzelne compilation unit; einige verteilt wird Sie an die aufrufende Modul.

    Im Falle einer Schnur, die ich weitergeben würde eine const char * (oder const wchar_t * oder const TCHAR *) und führen Sie die Konvertierung zu std::string oder CString auf der anderen Seite der Schnittstelle, die innerhalb der DLL.

    • Nicht nur Vorlagen, jede Klasse mit inline-Memberfunktionen wird ein layout erstellen-Abhängigkeit.
    • wahr genug. Aber Vorlagen sind per definition eingebettet, so die Warnung gilt doppelt für Sie.
    • Danke für deine Idee, ich werde es tun !

Kostenlose Online-Tests

Letzte Fragen

Tun ItemView löst Blase?

Ich habe eine CompositeView für eine Tabelle. Ich habe Trigger-set in der Kind-ItemView für jede Zeile... var TableRow = Marionette.ItemView.extend({ tagName:...

Wie kann ich untersuchen, WCF was 400 bad request über GET?

Die folgenden WCF-endpoint funktioniert gut mit dem WCF test client: AssetList ListFlaggedAssets(short processCode, string platform, string endpoint = "null", string portalId = "null", int...

Bei der Verwendung von UUIDs, sollte ich auch mit AUTO_INCREMENT?

Wir bauen eine neue web-app, die eine offline-iPad - /Android-app-version auf einer Reihe von lokalen Geräten, die Einsätze mit neuen Daten. Als solche benötigen...

Actionscript-Objekt, das verschiedene Eigenschaften

Wie kann ich die Anzahl der Eigenschaften in einer generischen Actionscript-Objekt? (Wie die Array-Länge) InformationsquelleAutor Fragsworth | 2011-01-15

Wie plot mehrere Graphen und nutzen Sie die Navigations-Taste im [matplotlib]

Die neueste version von matplotlib erstellt automatisch Navigations-buttons unter den graph. Aber die Beispiele, die ich finden alles im Internet zeigen, wie erstellen Sie...