Wykorzystanie VCLTee.Chart w bibliotece BPL na 64-bit Win

problemy z funkcjonowaniem bibliotek, komponentów itp.

Wykorzystanie VCLTee.Chart w bibliotece BPL na 64-bit Win

Nowy postprzez Yaroda » środa, 7 października 2020, 14:10

Witam,

Słowem wstępu, chcę przekompilować mój stary projekt grupowy na platformę 64-bit Windows, składający się m.in. z kilku bibliotek BPL, który wcześniej był skompilowany na platformie 32-bit Windows i działał sprawnie. W jednej z bibliotek wykorzystuję klasy operujące na komponentach TChart. Zawarte w niej klasy i metody operujące na obiektach typu TChart są uniwersalne i korzystam z nich w różnych projektach, dlatego zawarłem je w osobnej bibliotece BPL.
Doszedłem do tego, że podczas linkowania biblioteki BPL, w której zawarte są pliki z definicjami klas operującymi na komponentach TChart, a w plikach nagłówkowych jest odwołanie do biblioteki TChart, czyli #include <VCLTee.Chart.hpp>, pojawia się błąd linkera.
Aby uprościć analizę zbudowałem pusty projekt grupowy, który zawiera tylko jedną bibliotekę BPL i projekt EXE z typową formatką VCL. W testowej bibliotece BPL mieści się tylko jeden plik Unit z linkiem #include <VCLTee.Chart.hpp> zamieszczonym w pliku nagłówkowym. Nie ma żadnej definicji klasy ani innego kodu, jak pokazano niżej:
Kod: Zaznacz cały
//---------------------------------------------------------------------------
#ifndef TestUnit64bitH
#define TestUnit64bitH
//---------------------------------------------------------------------------
#include <VCLTee.Chart.hpp>
//---------------------------------------------------------------------------
//..
//---------------------------------------------------------------------------
#endif

Lokalny build (Alt+F9) tego pliku, kończy się sukcesem. Natomiast build całego projektu z biblioteką BPL, kończy się błędem i pojawiają się następujące błędy linkera:

[ilink64 Error] Error: Unresolved external 'System::Generics::Collections::TList__1<Vcltee::Teengine::TChartAxis*>::TList__1()' referenced from C:\USERS\...\DOCUMENTS\EMBARCADERO\STUDIO\TESTS\TESTAPP64BIT\WIN64\DEBUG\TESTUNIT64BIT.O
[ilink64 Error] Error: Unresolved external 'System::Generics::Collections::TList__1<Vcltee::Teengine::TChartAxis*>::TList__1(System::DelphiInterface<System::Generics::Defaults::IComparer__1<Vcltee::Teengine::TChartAxis*> >)' referenced from C:\USERS\...\DOCUMENTS\EMBARCADERO\STUDIO\TESTS\TESTAPP64BIT\WIN64\DEBUG\TESTUNIT64BIT.O
[ilink64 Error] Error: Unresolved external 'System::Generics::Collections::TList__1<Vcltee::Teengine::TChartAxis*>::TList__1(System::Generics::Collections::TEnumerable__1<Vcltee::Teengine::TChartAxis*>*)' referenced from C:\USERS\...\DOCUMENTS\EMBARCADERO\STUDIO\TESTS\TESTAPP64BIT\WIN64\DEBUG\TESTUNIT64BIT.O
[ilink64 Error] Error: Unresolved external 'System::Generics::Collections::TList__1<Vcltee::Teengine::TSeriesMarkPosition*>::TList__1()' referenced from C:\USERS\...\DOCUMENTS\EMBARCADERO\STUDIO\TESTS\TESTAPP64BIT\WIN64\DEBUG\TESTUNIT64BIT.O
[ilink64 Error] Error: Unresolved external 'System::Generics::Collections::TList__1<Vcltee::Teengine::TSeriesMarkPosition*>::TList__1(System::DelphiInterface<System::Generics::Defaults::IComparer__1<Vcltee::Teengine::TSeriesMarkPosition*> >)' referenced from C:\USERS\...\DOCUMENTS\EMBARCADERO\STUDIO\TESTS\TESTAPP64BIT\WIN64\DEBUG\TESTUNIT64BIT.O
[ilink64 Error] Error: Unresolved external 'System::Generics::Collections::TList__1<Vcltee::Teengine::TSeriesMarkPosition*>::TList__1(System::Generics::Collections::TEnumerable__1<Vcltee::Teengine::TSeriesMarkPosition*>*)' referenced from C:\USERS\...\DOCUMENTS\EMBARCADERO\STUDIO\TESTS\TESTAPP64BIT\WIN64\DEBUG\TESTUNIT64BIT.O
[ilink64 Error] Error: Unresolved external 'System::Generics::Collections::TList__1<Vcltee::Teengine::TMarksItem*>::TList__1()' referenced from C:\USERS\...\DOCUMENTS\EMBARCADERO\STUDIO\TESTS\TESTAPP64BIT\WIN64\DEBUG\TESTUNIT64BIT.O
[ilink64 Error] Error: Unresolved external 'System::Generics::Collections::TList__1<Vcltee::Teengine::TMarksItem*>::TList__1(System::DelphiInterface<System::Generics::Defaults::IComparer__1<Vcltee::Teengine::TMarksItem*> >)' referenced from C:\USERS\...\DOCUMENTS\EMBARCADERO\STUDIO\TESTS\TESTAPP64BIT\WIN64\DEBUG\TESTUNIT64BIT.O
[ilink64 Error] Error: Unresolved external 'System::Generics::Collections::TList__1<Vcltee::Teengine::TMarksItem*>::TList__1(System::Generics::Collections::TEnumerable__1<Vcltee::Teengine::TMarksItem*>*)' referenced from C:\USERS\...\DOCUMENTS\EMBARCADERO\STUDIO\TESTS\TESTAPP64BIT\WIN64\DEBUG\TESTUNIT64BIT.O
[ilink64 Error] Error: Unresolved external 'System::Generics::Collections::TList__1<Vcltee::Teengine::TChartValueList*>::TList__1()' referenced from C:\USERS\...\DOCUMENTS\EMBARCADERO\STUDIO\TESTS\TESTAPP64BIT\WIN64\DEBUG\TESTUNIT64BIT.O
[ilink64 Error] Error: Unresolved external 'System::Generics::Collections::TList__1<Vcltee::Teengine::TChartValueList*>::TList__1(System::DelphiInterface<System::Generics::Defaults::IComparer__1<Vcltee::Teengine::TChartValueList*> >)' referenced from C:\USERS\...\DOCUMENTS\EMBARCADERO\STUDIO\TESTS\TESTAPP64BIT\WIN64\DEBUG\TESTUNIT64BIT.O
[ilink64 Error] Error: Unresolved external 'System::Generics::Collections::TList__1<Vcltee::Teengine::TChartValueList*>::TList__1(System::Generics::Collections::TEnumerable__1<Vcltee::Teengine::TChartValueList*>*)' referenced from C:\USERS\...\DOCUMENTS\EMBARCADERO\STUDIO\TESTS\TESTAPP64BIT\WIN64\DEBUG\TESTUNIT64BIT.O
[ilink64 Error] Error: Unresolved external 'System::Generics::Collections::TList__1<Vcltee::Tecanvas::TVisualBlock*>::TList__1()' referenced from C:\USERS\...\DOCUMENTS\EMBARCADERO\STUDIO\TESTS\TESTAPP64BIT\WIN64\DEBUG\TESTUNIT64BIT.O
[ilink64 Error] Error: Unresolved external 'System::Generics::Collections::TList__1<Vcltee::Tecanvas::TVisualBlock*>::TList__1(System::DelphiInterface<System::Generics::Defaults::IComparer__1<Vcltee::Tecanvas::TVisualBlock*> >)' referenced from C:\USERS\...\DOCUMENTS\EMBARCADERO\STUDIO\TESTS\TESTAPP64BIT\WIN64\DEBUG\TESTUNIT64BIT.O
[ilink64 Error] Error: Unresolved external 'System::Generics::Collections::TList__1<Vcltee::Tecanvas::TVisualBlock*>::TList__1(System::Generics::Collections::TEnumerable__1<Vcltee::Tecanvas::TVisualBlock*>*)' referenced from C:\USERS\...\DOCUMENTS\EMBARCADERO\STUDIO\TESTS\TESTAPP64BIT\WIN64\DEBUG\TESTUNIT64BIT.O


Ewidentnie jest to błąd związany z linkowaniem składowych komponentu TChart w tworzonej bibliotece BPL na platformie 64-bit Windows.
Czy ktoś spotkał się z takim problemem i jak go obejść?

Pozdrawiam
Yaroda
May the Force be with you
Avatar użytkownika
Yaroda
Bladawiec
Bladawiec
 
Posty: 3
Dołączył(a): środa, 7 października 2020, 13:10
Podziękował : 0
Otrzymał podziękowań: 0
System operacyjny: Windows 10
Kompilator: C++Builder 10.2 Tokyo Professional
Gadu Gadu: 0
    WindowsFirefox

Re: Wykorzystanie VCLTee.Chart w bibliotece BPL na 64-bit Win

Nowy postprzez polymorphism » środa, 7 października 2020, 18:41

Nawiasem: ten testowy projekt powinien zawierać jakiś kod odwołujący się do metod TChart, byś mógł określić, czy problem leży w starym projekcie, czy w środowisku/bibliotece/whatever. Samo załączenie nagłówka nic nie znaczy.
C++ Reference - opis wszystkich klas STL-a i funkcji C.
Avatar użytkownika
polymorphism
Doświadczony Programista ● Moderator
Doświadczony Programista ● Moderator
 
Posty: 2264
Dołączył(a): piątek, 19 grudnia 2008, 13:04
Podziękował : 0
Otrzymał podziękowań: 210
System operacyjny: Windows 8.1
Windows 10
Linux Mint 19
Kompilator: Visual Studio
Visual Studio Code
MSYS2 (MinGW, clang)
g++
clang
Gadu Gadu: 0
    UbuntuFirefox

Re: Wykorzystanie VCLTee.Chart w bibliotece BPL na 64-bit Win

Nowy postprzez Yaroda » czwartek, 8 października 2020, 20:59

Właśnie dlatego pokazuję to na przykładzie testowego projektu właściwie bez linii własnego kodu a jedynie z dyrektywą include, włączającą do procesu kompilacji projektu plik nagłówkowy <VCLTee.Chart.hpp>, w którym zawarte są deklaracje atrybutów z właściwościami wykresu oraz definicje konstruktorów i destruktora klasy/komponentu TChart, a także innych klas współtworzących komponent TChart.
Problem jest w tym, że gdy kompiluje i tworzę tę bibliotekę testową w tej postaci na platformę 32-bit Windows to tworzenie biblioteki BPL odbywa się bez błędu – projekt się kompiluje i linkuje, i w efekcie powstaje plik z biblioteką *.bpl. Natomiast gdy chcę go zbudować na platformę 64-bit Windows to pojawiają się błędy, które wcześniej pokazałem. Tak jakby linker nie pozwalał zbudować projektu Borland Package Library na platformie 64-bit Windows, w którym zwarte są komponenty (TChart) opracowane dawno temu jeszcze za pomocą kodu Delphi (Pascala). Co ciekawe projekt z plikiem wykonywalnym (*.exe) na platformę 64-bit Windows, który zawiera obiekty typu TChart i w związku z tym dyrektywę include, włączającą do projektu plik nagłówkowy <VCLTee.Chart.hpp>, kompiluje i linkuje się bezproblemowo, a następnie uruchamia okno aplikacji z widocznym wykresem itd.
W opcjach projektu w zakładce „C++ Linker” oczywiście ustawione mam następujące właściwości:
- Full debug information: True
- Link with Dynamic RTL: False
May the Force be with you
Avatar użytkownika
Yaroda
Bladawiec
Bladawiec
 
Posty: 3
Dołączył(a): środa, 7 października 2020, 13:10
Podziękował : 0
Otrzymał podziękowań: 0
System operacyjny: Windows 10
Kompilator: C++Builder 10.2 Tokyo Professional
Gadu Gadu: 0
    WindowsFirefox

Re: Wykorzystanie VCLTee.Chart w bibliotece BPL na 64-bit Win

Nowy postprzez Yaroda » piątek, 9 października 2020, 01:26

Ok, chyba sam się nakierowałem na rozwiązanie problemu.
Przejrzałem plik <VCLTee.Chart.hpp> i znalazłem tam wielokrotne zastosowanie dyrektywy preprocesora #ifndef pozwalającej na warunkową kompilację fragmentu kodu źródłowego, jeżeli makronazwa _WIN64 nie jest zdefiniowana, jak np. w definicji klasy „TCustomChart”:

Kod: Zaznacz cały
class PASCALIMPLEMENTATION TCustomChart : public Vcltee::Teengine::TCustomAxisPanel
{
   typedef Vcltee::Teengine::TCustomAxisPanel inherited;
   
private:
   int FColorPaletteIndex;
//...
   void __fastcall BroadcastKeyEvent(Vcltee::Teengine::TChartKeyEvent AEvent, System::Word &Key, System::WideChar &Key1, System::Classes::TShiftState Shift);
#ifndef _WIN64
   Vcltee::Teengine::TChartClickedPart __fastcall CalcNeedClickedPart(const System::Types::TPoint &Pos, bool Needed);
#else /* _WIN64 */
   Vcltee::Teengine::TChartClickedPart __fastcall CalcNeedClickedPart(System::Types::TPoint Pos, bool Needed);
#endif /* _WIN64 */
   bool __fastcall CanWheelScroll(void);
//...
protected:
   bool RestoredAxisScales;
   virtual void __fastcall CalcWallsRect(void);
   virtual int __fastcall CalcWallSize(Vcltee::Teengine::TChartAxis* Axis);
   DYNAMIC void __fastcall CalcZoomPoints(void);
   virtual void __fastcall DefineProperties(System::Classes::TFiler* Filer);
#ifndef _WIN64
   DYNAMIC bool __fastcall DoMouseWheel(System::Classes::TShiftState Shift, int WheelDelta, const System::Types::TPoint &MousePos);
   DYNAMIC bool __fastcall DoMouseWheelDown(System::Classes::TShiftState Shift, const System::Types::TPoint &MousePos);
   DYNAMIC bool __fastcall DoMouseWheelUp(System::Classes::TShiftState Shift, const System::Types::TPoint &MousePos);
#else /* _WIN64 */
   DYNAMIC bool __fastcall DoMouseWheel(System::Classes::TShiftState Shift, int WheelDelta, System::Types::TPoint MousePos);
   DYNAMIC bool __fastcall DoMouseWheelDown(System::Classes::TShiftState Shift, System::Types::TPoint MousePos);
   DYNAMIC bool __fastcall DoMouseWheelUp(System::Classes::TShiftState Shift, System::Types::TPoint MousePos);
#endif /* _WIN64 */

//...

public:
   __fastcall virtual TCustomChart(System::Classes::TComponent* AOwner);
   __fastcall virtual ~TCustomChart(void);
   virtual void __fastcall Assign(System::Classes::TPersistent* Source);
   System::UnicodeString __fastcall AxisTitleOrName(Vcltee::Teengine::TChartAxis* const Axis);
#ifndef _WIN64
   void __fastcall CalcClickedPart(const System::Types::TPoint &Pos, /* out */ Vcltee::Teengine::TChartClickedPart &Part);
#else /* _WIN64 */
   void __fastcall CalcClickedPart(System::Types::TPoint Pos, /* out */ Vcltee::Teengine::TChartClickedPart &Part);
#endif /* _WIN64 */
   DYNAMIC void __fastcall DragDrop(System::TObject* Source, int X, int Y);
//...
};

Na przykładzie testowego projektu, który przedstawiłem na początku, wystarczyło wprowadzić zapis z dyrektywą preprocesora #ifndef z makronazwą _WIN64 przed includem pliku nagłówkowego <VCLTee.Chart.hpp>, jak niżej:
Kod: Zaznacz cały
//---------------------------------------------------------------------------

#ifndef TestUnit64bitH
#define TestUnit64bitH
//---------------------------------------------------------------------------
#ifndef _WIN64
#include <VCLTee.Chart.hpp>
#endif
//---------------------------------------------------------------------------
//..
//---------------------------------------------------------------------------
#endif

W efekcie wszystko działa – projekt się kompiluje i linker nie zgłasza problemów przy utworzeniu biblioteki na platformie 64-bit Windows.
Temat uznaję za zamknięty! :D
May the Force be with you
Avatar użytkownika
Yaroda
Bladawiec
Bladawiec
 
Posty: 3
Dołączył(a): środa, 7 października 2020, 13:10
Podziękował : 0
Otrzymał podziękowań: 0
System operacyjny: Windows 10
Kompilator: C++Builder 10.2 Tokyo Professional
Gadu Gadu: 0
    WindowsFirefox


  • Podobne tematy
    Odpowiedzi
    Wyświetlone
    Ostatni post

Powrót do Biblioteki i komponenty

Kto przegląda forum

Użytkownicy przeglądający ten dział: Brak zalogowanych użytkowników i 1 gość

cron