Jak napisać klasę w bibliotece dynamicznej, a przede wszystkim jak ją za importować do programu aby móc jej używał poprzez linkowanie dynamiczne?? BARDZO PROSZĘ O POMOC. Dobrze byłoby gdyby to był C++ Builder.
Chodzi ci najwyraźniej o coś co nazywa się plugin.
Filozofia jest prosta
- definiujesz interface (plik nagłówkowy wspólny dla dll'ki i jej użytkowników):
class TInerface {
public:
virtual int jaksaMetoda1() = 0;
virtual void jaksaMetoda2(int, int) = 0;
virtual int jaksaMetoda3(double, const char*) = 0;
virtual int jaksaMetoda4() const = 0;
virtual ~TInerface()
{}
};
- W dll-ce tworzysz klasę dziedziczącą po tym interface (implementacja nieistotana), i tworzysz metodę exportowalną, która będzie generowała obiekty tej klasy (sama klasa pozostaje nieeksportowalna):
extern "C" __declspec( dllexport ) TInerface* fabryka(int argument1, char* argument2) {
return new TwojaKlasaRozszerzajacaTInerface(argument1,argument2);
}
- potem ładujesz dll, odczytujesz adres metody fabryka i wywołujesz ją za każdym razem kiedy potrzebujesz nowego obiektu tej klasy z dynamicznie podwiązanej biblioteki. Dla tych obiektów wykorzystując polimorfizm, możesz korzystać z metod interface'u TInerface. I tyle :)
nie da się dynamicznie, nie ma odpowiednika GetProcAddress, który by obsługiwał konwencję metod _thiscall
ale można sobie napisać mechanizm, który przekształci metody na funkcje, które jako pierwszy parametr pobierają this:
dla _thiscall => _stdcall
czyli coś typu:
Obiekt->Metoda(parametr); przerobi na Metoda(&Obiekt,parametr); //(mechanizm uchwytów)
//UP, albo i tak
Hmm... dzięki za odpowiedzi. Z bibliotekami miałem prawdę mówiąc bardzo mało styczności. Właściwie to pierwsza moja wykorzystywana w projekcie.
Chodziło mi o coś takiego:
Mam aplikację która ma na jakimś Panelu, a właściwie Framesie jakieś komponenty z zasobami i generalnie troszkę zajmuje pamięci. Program, który piszę może działać w dwóch trybach w zależności od wyboru użytkownika. Użytkownik może korzystać z tej ramki albo nie. Może ją załadować także w czasie działania programu.
Chciałem dlatego tą ramkę umieścić w bibliotece DLL tak aby użytkownik mógł w ją ładować lub nie. W pewnych momentach przyspieszało by to działanie aplikacji.
Gdy w Builderze tworzę nową ramkę tworzy mi się klasa. Gdy chcę aby taka ramka była w bibliotece to ciągle jest to klasa. I teraz nie wiem jak sobie z tym poradzić. Może propozycje jakieś....
Coś mam wrażenie, że przekombinowałeś. Sama klasa zajmuje w pamięci tyle co nic. Dopóki nie stworzysz obiektu tej klasy nie ma znaczenia, co zawiera ta klasa, pamięci zawsze zeżre niewiele. Zastanów się czy na pewno warto robić tu dll-kę, a czy czasami nie wystarcz tworzyć i niszczyć obiekt samemu.
Na Framesie umieszczam około 4 MB zasobów, więc to wszystko wejdzie w skład exeka. Większy rozmiar aplikacji - dłużysz czas ładowania i więcej zużytej pamęci? Mam rację czy rzeczywiście przekombinowałem?
A co to jest 4MB w dzisiejszych czasach? Drobniaki. Dziś byle aplikacja zjada na starcie 40 MB.
Poza tym jak się upierasz to ci już dałem rozwiązanie, z tą różnicą, że twoja klasą bazową jest: TFrame (lub coś podobnego).
Na dodatek, jak ktoś piszę w Builderze to raczej nie przejmuje za bardzo się zasobami. To jest środowisko do szybkiego pisania aplikacji, a nie do pisania wydajnych aplikacji.
MarekR22 napisał(a)
Poza tym jak się upierasz to ci już dałem rozwiązanie, z tą różnicą, że twoja klasą bazową jest: TFrame (lub coś podobnego).
Na pewno TFrame?? Jak stworzę sobię Ramkę zostanie utworzona taka klasa:
class TRamka : public TFrame;
Gdy do tej ramki dodam jakieś komponenty to jak będę zwracał TFrame to nie będę miał dostępu do tych komponentów. Czy zatem nie powinno być tak że tworzę dodatkową klasę i dziedziczę ją po TRamka i obiekt tej nowo utworzonej klasy zwracam?
class TRamkaNew : public TRamka;
Tak powinno być?