Frage

Ist es möglich, Ressourcen in eine statische Bibliothek zu erstellen und wiederverwenden, indem Sie einfach mit der Bibliothek verknüpfen?

Ich denke in erster Linie um den Fall, dass Sie eine Funktion in der Bibliothek aufrufen, die wiederum greift auf Ressourcen.

War es hilfreich?

Lösung

Es kann getan werden, aber es ist sehr schmerzhaft. Sie können es nicht tun, indem Sie einfach mit der statischen Bibliothek verknüpft

Bedenken Sie: Ressourcen werden in einer EXE oder DLL eingebettet. Wenn einige Code in den statischen Bibliothek Anrufen (z) LoadIcon, wird es die Ressourcen aus dem EXE oder DLL erhalten, die es mit verknüpft ist.

Also, wenn Ihre statische Bibliothek Ressourcen erfordert zur Verfügung steht, haben Sie ein paar Optionen bekommen:

  1. Sie können haben die Bibliothek sie schnell bauen, und dann verwenden (z) CreateDialogIndirect. Siehe Raymond Chen „Der Aufbau einer Dialogvorlage zur Laufzeit“ .
  2. Sie können sie in der Bibliothek eingebettet haben als einfache Arrays (d) char my_dialog_resource[] = { .... };, und dann verwenden (z) CreateDialogIndirect. Sie müssen wahrscheinlich finden (oder schreiben) ein Dienstprogramm, das von .RES Dateien konvertiert Dateien .CPP.
  3. Sie können mit einer Ressource-Skript (.RC-Datei) und die entsprechenden Header-Datei, die LIB-Datei versenden. Sie #include dann als relevant. Sie müssen eine Reihe von Ressourcen-IDs reserviert für die LIB, zu verwenden, so dass sie mit denen des Haupt EXE oder DLL nicht kollidieren. Dies ist, was MFC tut, wenn sie als eine statische Bibliothek verwendet. Oder Sie können String-Ressourcen-IDs verwenden (dies funktioniert nicht für STRINGTABLE Ressourcen).
  4. Ihre statische Bibliothek kann mit einem separaten Ressource-DLL versenden.

Andere Tipps

Das einzige, was Sie tun müssen, um Ressourcen (Bilder, Dialoge, etc ...) in einer statischen Bibliothek in Visual C ++ (2008), ist gehören die statische Bibliothek zugehörige Re-Datei in Ihrem Projekt. Dies kann bei „Projekteinstellungen / Linker / Input / zusätzliche Abhängigkeiten“ erfolgen.

Mit dieser Lösung werden die Ressourcen der statischen Bibliothek werden in die EXE gepackt, so dass Sie nicht eine zusätzliche DLL benötigen. Bedauerlicherweise Visual Studio umfasst nicht die .res Datei automatisch, wie es funktioniert für die LIB-Datei (wenn die „Projektabhängigkeiten“ -Feature verwenden), aber ich denke, dieser kleine zusätzliche Schritt ist akzeptabel.

Ich habe für eine sehr lange Zeit für diese Lösung gesucht, und jetzt überrascht es mir, es ist so einfach. Das einzige Problem ist, dass es völlig undokumentiert.

Ich ging gerade durch diesen mit den MS Visual Studio-Compiler. Wir waren einige ältere Projekte von DLLs in statischen Bibliotheken zu konvertieren. Mehrere dieser DLLs hatte Dialog oder String-Ressourcen in sie eingebettet. Ich war in der Lage, die .RC Skripte für diesen DLLs in unsere Anwendung zu kompilieren, indem sie in der Hauptanwendung der RC-Skriptdatei über den „TEXTINCLUDE“ Mechanismus. Ich fand es am einfachsten, dies zu tun, indem Sie die RC-Datei direkt, aber Visual Studio bietet einen etwas „wizardy“ Mechanismus als auch. Die Implementierung ist höchstwahrscheinlich anders in anderen Compilern.


Um das Haupt RC Skript zu manipulieren direkt:

0,1. In dem „2 TEXTINCLUDE“ Abschnitt, umfasst die Header-Datei, die die Ressourcen-IDs für Ihre Bibliothek definiert. Die Syntax ist

2 TEXTINCLUDE 
BEGIN
    "#include ""my_first_lib_header.h""\r\n"
    "#include ""my_second_lib_header.h""\0" 
END

0,2. In dem "3 TEXTINCLUDE" Abschnitt, umfasst den RC-Skript aus Ihrer Bibliothek.

3 TEXTINCLUDE
BEGIN
    "#include ""my_first_library.rc""\r\n"
    "#include ""my_second_library.rc""\0"
END

Die Schritte 3 und 4 soll automatisch geschehen, aber ich fand es zuverlässiger war nur sie selbst zu geben, anstatt in Abhängigkeit von Microsofts Ressource-Skript-Compiler Pflege der Dinge zu nehmen.

0,3. Fügen Sie die Header-Datei mit Ihren Bibliotheken Ressource nur Symbole Liste zum Lesen definiert. Diese Liste ist in der Regel in der Nähe der Anfang der Datei.

#define APSTUDIO_READONLY_SYMBOLS
#include "my_first_lib_header.h"
#include "my_second_lib_header.h"
#undef APSTUDIO_READONLY_SYMBOLS

0,4. Fügen Sie Ihre Bibliothek RC-Skript im APSTUDIO_INVOKED Abschnitt. Dies ist in der Regel am Ende der Datei.

#ifndef APSTUDIO_INVOKED
#include "my_first_library.rc"
#include "my_second_library.rc"
#endif 

können Sie auch tun, all dies automatisch durch die Visual Studio-IDE, aber ich fand es galt nicht immer, als ich es erwartet hat.

  1. Öffnen Sie die "Ressourcenansicht" Fenster in Visual Studio.
  2. Rechtsklick auf Ihrer Haupt-Ressource-Datei der Anwendung und wählen Sie „Ressourcen Enthalten ...“ aus dem Kontextmenü.
  3. Im Feld „Read-only-Symbol-Richtlinien“, fügen Sie die Anweisungen für die H-Dateien enthalten, die die Ressource-IDs für Ihre Bibliotheken definieren.
  4. In dem Feld „Compiler-Direktiven“, fügen Sie die Anweisungen für Ihre Bibliothek .rc Skript enthalten.
  5. Klicken Sie auf OK. Sie können auch manuell die RC Skriptkompilierung auszulösen, um sicherzustellen, dass es passiert.

Wenn Sie Ihre Bibliothek Ressource-Skript alle Dateien auf der Festplatte (Textdateien, Icons Dateien, etc.) verweist, müssen Sie sicherstellen, dass das Hauptanwendungsprojekt weiß, wo sie zu finden. Sie können entweder diese Dateien irgendwo Ihre Anwendung kopieren Sie sie finden können, oder Sie können hinzufügen eine zusätzliche Include-Pfad in den Compiler-Einstellungen.

So fügen Sie eine zusätzliche Include-Pfad:

  1. Öffnen Sie die Eigenschaften für das Hauptanwendungsdialog.
  2. Wählen Sie „Konfigurationseigenschaften / Ressourcen / Allgemein“ aus dem linken Navigationsbereich.
  3. In der Liste Eigenschaften Geben Sie alle relevanten Pfade neben „Zusätzliche Includeverzeichnisse.“

Das glaube ich nicht so. Statische Bibliothek verfügt nicht über seine eigene HINSTANCE. Es ist Code im Kontext des DLL oder EXE ausgeführt, die sie verbindet. Deshalb werden alle Ressourcen, die Sie werde versuchen, von der statischen Bibliothek Code zu laden, wird dieses umschließenden DLL / EXE sein.

habe ich diese Art von Ressourcen mit einer DLL Wiederverwendung obwohl, soweit es seine eigene Adressraum hat, und Sie können mit Load DLL HINSTANCE nennen.

Wie pro Visual Studio 2010, die Entwicklungstools von Microsoft offenbar nicht richtig an allen Ressourcendaten innerhalb statischer Bibliotheken zusammengestellt Griff.

Um eine kompilierte Ressource-Datei (eine .res-Datei) zu verteilen, haben Sie zwei Möglichkeiten:

  1. Verteilen Sie die .res Dateien getrennt, und sie anweisen Code den Client gegen sie zu verbinden;
  2. Verwenden Sie cvtres mehrere .res Dateien zu einem einzigen Objekt (.obj) Datei zu verschmelzen, und liefern sie separat.

Beachten Sie, dass Sie nicht in Objektdateien erstellt mit cvtres lib können. Wenn mehrere Objektdateien zur Verfügung gestellt werden, klagt lib als ob als mehrere .res Dateien gegeben wurden; wenn eine einzelne Objekt-Datei zur Verfügung gestellt wird, ist lib nicht beschweren, aber der Linker einfach ignoriert die eingebetteten Ressource-Daten in der Datei lib.

Es könnte der Fall sein, dass es eine Möglichkeit, den Linker zu zwingen, ist die befreite in Ressourcendaten (mit einiger Befehlszeilenoption, Abschnitt Manipulation usw.), da die Ressourcendaten zu lesen und zu verknüpfen ist in der Tat in dem Bibliothek (wie dumpbin offenbart). Bisher habe ich noch keine Lösung gefunden, und, es sei denn, man ist bereit, die Entwicklungs-Tools zu hacken, etwas besser als diese einfache Lösung ist wahrscheinlich nicht der Mühe wert.

Die einzige Möglichkeit, Ressourcendaten in einer statischen Bibliothek (in diesem Fall mit einer statischen Bibliothek) zu versenden ist es, die Ressourcen separat zu verteilen und sie explizit im Client-Code zu verknüpfen. cvtres unter Verwendung der Anzahl von verteilten Ressourcen-Dateien auf eine reduzieren kann, wenn man viele von ihnen haben.

Die empfohlene Methode ist eine DLL mit den Ressourcen bereitzustellen, zusammen mit Ihrer Bibliothek.

Wenn das folgende Verfahren verwendet wird, eine beliebige Ressource (in diesem Beispiel ein Symbol) kann als integraler Bestandteil einer statischen Bibliothek und eine solche Bibliothek verwendet werden kann durch jede Art von Anwendung verwendet werden, einschließlich einer Konsole ein (die doesn ‚t eine Ressource Segment hat auch immer).

  1. Icon wird auf eine statische Anordnung von BYTE umgewandelt. bin2c können dafür verwendet werden.
  2. Die Daten werden in einem HICON Griff umgewandelt. Hier ist, wie ich das getan habe:

    HICON GetIcon()
    { 
       DWORD dwTmp;
       int offset;
       HANDLE hFile;
       HICON hIcon = NULL;
       offset = LookupIconIdFromDirectoryEx(s_byIconData, TRUE, 0, 0, LR_DEFAULTCOLOR);
       if (offset != 0)
       {
          hIcon = CreateIconFromResourceEx(s_byIconData + offset, 0, TRUE, 0x00030000, 0, 0, LR_DEFAULTCOLOR | LR_DEFAULTSIZE);
       }
       return hIcon;  
    }
    
  3. GetIcon statt LoadIcon verwendet. Statt Aufruf:

m_hIcon = ::LoadIcon(hInstanceIcon, MAKEINTRESOURCE(pXMB->nIcon));

Dann ruft

m_hIcon = GetIcon()
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top