XE3 Packages teilweise linken



  • Hallo zusammen,

    habe versucht mit dem XE3 eine alte DLL neu zu übersetzen.
    Bei Packages habe ich immer die VCL und RTL mit drin (d.h. vcl*.bpl und rtl*.bpl) muß auf dem Zielsystem vorhanden sein).

    Bei dieser DLL wir allerdings immer vclimg*.bpl verlangt.

    Die DLL bindet den Header jpeg.h ein.
    In diesem steht quasi:

    #ifdef USEPACKAGES
     #pragma link "vclimg.bpi"
    #else
     #ifndef _WIN64
      #pragma link "vclimg.lib"
     #else
      #pragma link "vclimg.a"
     #endif
    #endif
    #pragma link "Vcl.Imaging.jpeg"
    

    USEPACKAGES ist beim compilieren gesetzt, d.h. er linkt vclimg.bpi welches wiederum vclimg*.bpl benötigt.
    Ist meine Schlussfolgerung richtig, und wie kann ich dies abstellen?

    MfG Stephan



  • Wenn du unter "Projektoptionen->Packages->Laufzeit->Packages" bei "Mit Laufzeit Packages linken" den Haken wegnimmst, also auf false setzen, sollte es klappen. Es sollte dann nur vclimg.lib eingebunden werden.



  • Hallo Burkhi

    Burkhi schrieb:

    Wenn du unter "Projektoptionen->Packages->Laufzeit->Packages" bei "Mit Laufzeit Packages linken" den Haken wegnimmst, also auf false setzen, sollte es klappen. Es sollte dann nur vclimg.lib eingebunden werden.

    Das ist mir soweit schon klar, allerdings würde ich gerne das vcl und rtl Laufzeitpackage verwenden, und habe deshalb den Hacken an.
    Gibt es für diese Konstellation eine Lösung, oder muss ich den Header manipulieren?

    MfG Stephan



  • Stephan schrieb:

    Hacken

    Die Hacken laß bitte in den Schuhen, während wir uns auf den Haken konzentrieren 🙂

    Stephan schrieb:

    USEPACKAGES ist beim compilieren gesetzt, d.h. er linkt vclimg.bpi welches wiederum vclimg*.bpl benötigt.
    Ist meine Schlussfolgerung richtig

    Ja. Das ist ein Artefakt unzulänglichen Designs bei der Package-Einbindung im C++Builder.

    Bei Delphi gibt es keine Separation zwischen Compiler und Linker; der Compiler kümmert sich selbst um alle Abhängigkeiten zu Packages. Er weiß, daß du ein bestimmtes Package benötigst, wenn du ein Unit daraus referenzierst ("uses Jpeg"). Der Compiler bekommt die in den Projektoptionen festgelegte Liste an Packages übergeben, und wenn das fragliche Package für eine Unit darin enthalten ist, referenziert er das Package, andernfalls behandelt er das Unit ähnlich wie eine statische Bibliothek.

    In C++ sind Compiler und Linker getrennt. Der Compiler erzeugt in jeder Objektdatei eine Reihe von Abhängigkeiten (d.h. externen Symbolen), die der Linker auflösen muß. Der Linker hat dabei keine Ahnung, woher diese Symbole kommen sollen, und ist darauf angewiesen, daß man ihm eine Liste an Importbibliotheken (*.bpi oder *.lib), statischen Bibliotheken oder Objektdateien gibt, aus der er sich die Symbole zusammensucht. Die IDE könnte natürlich die gesamte Liste der Packages an den Linker weitergeben; aber dann würden immer alle Packages zugleich dynamisch oder statisch referenziert, und außerdem würde das Linken irrwitzig lange dauern und Unmengen an Arbeitsspeicher erfordern (zumal es in ILINK einige Designfehler gibt, die bei zu viel Input zu den lustigsten Problemen führen und sicher dem einen oder anderen hier hinlänglich bekannt sind).

    Also macht die IDE folgenden Kompromiß: sie stellt eine Liste der Packages zusammen, aus denen Designtime-Komponenten auf Formularen, Frames und Datenmodulen bezogen werden. Für Packages, die in der Package-Liste in den Projektoptionen als Laufzeit-Packages gelistet sind, gibt sie dem Compiler die .bpi-Datei (als Importbibliothek), für diejenigen, die nicht gelistet sind, die .lib-Datei (für statisches Linken).

    Offensichtlich klappt das nicht, wenn man eine Komponente nur im Code verwendet. Hätte Jpeg.hpp nicht extra diese #pragma-Statements bekommen, so würde die Verwendung von TJPEGImage mit einem Linkerfehler quittiert, solange man nicht explizit entweder vclimg.bpi oder vclimg.lib zum Projekt hinzufügt. Die #pragma-Statements sind also nur ein Workaround für das Problem, daß – anders als der Delphi-Compiler – der C++-Linker nicht wissen kann, welche Komponenten man im Code benutzt.

    Stephan schrieb:

    und wie kann ich dies abstellen?

    Neues Define einführen (etwa _STATIC_PACKAGE_VCLIMG ) und Headerdatei entsprechend anpassen.



  • Hallo Audacia,

    habe den Header nun so angepasst, da ich im Normalfall das Package nicht verwenden möchte.

    #ifdef USEPACKAGES
       #ifdef USEPACKAGES_VCLIMG
          #pragma link "vclimg.bpi"
       #else
           #warning "static linking VCLIMG, if you want to use the package vclimg*.bpl set the define USEPACKAGES_VCLIMG"
           #ifndef _WIN64
              #pragma link "vclimg.lib"
           #else
              #pragma link "vclimg.a"
           #endif
       #endif //#ifdef USEPACKAGES_VCLIMG
    #else
       #ifndef _WIN64
          #pragma link "vclimg.lib"
       #else
          #pragma link "vclimg.a"
       #endif
    #endif
    #pragma link "Vcl.Imaging.jpeg"
    

    Wenn ich nun so compiliere/linke bekomme ich vom Linker folgenden Fehler

    [ilink32 Fehler] Fatal: Datei 'SYSTEM.TYPES.OBJ' kann nicht geöffnet werden
    

    Bei den Bibliotheken ist der Pfad zu der DCU eingetragen.
    Wenn ich die entsprechende PAS Datei mit ins Projekt aufnehmen, wird eine neue angemeckert, und so geht es immer weiter.

    Irgendwelche Ideen?
    Was vielleicht noch eine Rolle spielt, das ganze wird in einer DLL verwendet.

    MfG Stephan



  • Hallo zusammen,

    hab's nun doch hin bekommen.
    Ganz doofer Fehler, in der Projektdatei war kein Framework angegeben. Hab nun VCL eingetragen, und nun funktioniert es auch ohne Modifikationen des JPG Headers.

    <FrameworkType>VCL</FrameworkType>
    

    Nochmals Vielen Dank an alle.
    MfG Stephan


Anmelden zum Antworten