Kto wywołał konstruktor (asm)

0

Cześć, tak sobie kombinuję, chcąc osiągnąć coś w stylu friend class z c++. A konkretnie chcę z jednej klasy wywołać konstruktor PRYWATNY innej klasy. Obydwie klasy są w innych unitach. Wiem, że Delphi mi na to nie pozwoli i konstruktor muszę uczynić PUBLIC. Jednak chcę mieć pewność, że konstruktor został wywołany przez konkretną klasę. Trochę eksperymentując z asemblerem, doszedłem do wniosku, że klasa wywołująca znajduje się pod adresem EBX + 64(dec) (system 32 b). I teraz pytanie, czy mogę założyć, że tak będzie zawsze? Tzn., czy w konstruktorze obiekt, który go wywołał zawsze będzie pod tym adresem?

0

Nie możesz tego założyć.

0

Don't trust the return address
To samo odnosi się do twojego przypadku: rejestry i stos da się spreparować.
Kombinując ryzykujesz luką bezpieczeństwa - co może nie mieć znaczenia w danym przypadku, ale po co pisać źle.

0

To czy w takim razie bez dodatkowych parametrów mogę dowiedzieć się, kto wywołał konstruktor/metodę? Kto, czyli obiekt, ewentualnie metoda, procedura

0

Tak, czytając informacje pozostawioną dla debugiera (o ile jest).

1

Ja nie rozumiem po co? Robienie na chama z Delphi C++ nie ma sensu.
Konstruktora w Delphi nie da się zrobić prywatnym i tego nie przeskoczysz, jeśli chcesz wiedzieć, który obiekt stworzył twój to podawaj w konstruktorze parametr "Sender" - tak jest przyjęte, widać twoje intencje bez robienia "hacków".
Zaś jeśli chodzi o coś w stylu przyjaźni wystarczy, że zadeklarujesz 2 klasy w tym samym module i wtedy mają dostęp do swoich prywatnych składowych.
Do tego RTTI zmieniło się od bodajże wersji Delphi 2010 i twój hack na callstack może nie zadziałać na innych wersjach, a jak pisałeś jeszcze o wykrywaniu metod może być jeszcze zabawniej przy virtual czy dynamic.

0

Można zrobić konstruktor prywatny - ten kto drukował z Delphi wie że jest coś takiego jak TPrinter (#!#%$@!).

Można też zrobić konstrukcję kontrolowaną - właśnie przy pomocy singletona.
Ale nie wiem czy o to chodziło autorowi wątku.
Deklarujesz globalną zmienną (dostępną przez jakieś tam akcesory) i... nie tworzysz w jej unicie obiektu (bo klasa zmiennej jest abstrakcyjna).
Robisz za to unit typu "implementation" który podstawia właściwy wskaźnik pod tę globalną zmienną.

@Juhas: napisz więcej o co Ci chodzi to może coś ciekawszego będzie można wykombinować.

Albo poczytaj o wzorcach projektowych:
http://www.castle-cadenza.demon.co.uk/pattern.htm

0

Singletony tworzę normalnie. Klasa z konstruktorem prywatnym (który oczywiście całkowicie przesłania domyślny konstruktor z TObject), funkcja w tym samym unicie zwracająca jedną instancję no i do tego odpowiedni kod w initialization i finalization. To nie jest problem. Chodzi o to, że mam w jednym unicie jedną klasę, a w drugim drugą. I chcę, żeby tak pozostało. Chcę uniknąć Sendera, bo chcę mieć pewność 100%, który obiekt wywołał mi konstruktor i pozwolić na utworzenie obiektu tylko wtedy, gdy konstruktor został wywołany przez obiekt odpowiedniej klasy. Widzę, że tak się chyba jednak nie da. Więc trudno.

0

Jeśli myślisz o zabezpieczeniu API to żadne ASM-owe sztuczki Ci raczej nie pomogą (bo również ASM-em je pewnie da się obejść).
Jeśli natomiast bardziej o zabezpieczenie "princypiów projektowych" to właśnie Printer można użyć jako wzorca.

API możesz zabezpieczyć udostępniając jego strukturalną / proceduralną wersję i wartości typu Handle zamiast wskaźniki na obiekty.

1 użytkowników online, w tym zalogowanych: 0, gości: 1