Wskaźnik jako parametr procedury

0

Przeczytałem artykuł o wskaźnikach i mam pewien problem. Napisałem taką procedurę:

procedure Pokaz(Value: PVariant);
begin
  Showmessage(String(Value));
end;

begin
  Pokaz(@Edit1.Text);  //String
  Pokaz(@SpinEdit1.Value);  //Integer
end;

Wyświetla mi błąd E2036 dlaczego?

2

Bo przekazujesz do procedury adres właściwości :D

0

Przerobiłem to tak że delphi mi teraz uruchamia program ale znowu coś źle robię

procedure Pokaz(Value: PVariant);
begin
  Showmessage(String(Value));
  Value^ := 'To powinno być w edit1';
end;
 
begin
  Pokaz(PVariant(Edit1.Text));  //String
end;

Nowa wartość nie pojawia się w okienku Edit1. Tak jakby PVariant(...) tworzył kopię stringa a nie odnosił się do adresu w edit1.text

3

Nie rozumiesz: Edit1.Text to nie jest pole, to jest właściwość.
Odwołując się do tego pola tak naprawdę wywołujesz metodę Edit1.GetText, która z kolei nie zwraca wskaźnika, zatem automatycznie w ten sposób nie możesz zmodyfikować tej wartości.
Nie mówiąc o tym dziwnym rzutowaniu na pvariant sugerującym, że nie masz do końca wiedzy o tym, jak działają wskaźniki.

1

Może warianty zostaw na razie w spokoju i naucz się dobrze bawić wskaźnikami:

type
  TShowAs = (saString, saInteger);

  procedure ShowValue(APointer: Pointer; AShowAs: TShowAs);
  begin
    case AShowAs of
      saString:  WriteLn('String:  ', String(APointer^));
      saInteger: WriteLn('Integer: ', Integer(APointer^));
    end;
  end;

var
  strValue: String = 'foo bald bar';
  intValue: Integer = 20;
begin
  ShowValue(@strValue, saString);
  ShowValue(@intValue, saInteger);
end.

Wyjście konsoli będzie wyglądać prawidłowo:

String:  foo bald bar
Integer: 20

Jeżeli już chcesz rzutować wartość spod wskaźnika na konkretny typ, to użyj wartości spod tego wskaźnika, czyli użyj operatora ^ np. przy wyświetlaniu.

0

Na zmiennych typu string , integer, double to już się bawiłem i tutaj to w miarę zrozumiałem. Natomiast doszedłem teraz do wniosku że aby zmienić czy pobrać aktualną wartość edit1.text to muszę pobrać adres komponentu Edit1 a nie właściwości. Myślałem że się da to zrobić prościej.

0

Jak chcesz do procedury pobrać adres obiektu to pobierasz adres obiektu; Jednak jeśli potrzebujesz pobrać dane z jakiegoś pola komponentu za pomocą właściwości (bo bezpośredniego dostępu nie masz, przynajmniej w poruszanym przypadku) to musisz te dane pobrać, zapisać do zmiennej i przekazać adres zmiennej, a nie obiektu;

Dlatego nic nie wychodziło, bo jeden bug wie czego adres zwróci @Edit1.Text, w każdym razie na pewno nie będzie to adres łańcucha znaków z pola FText klasy bazowej komponentu TEdit.

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