Modyfikacja adresu wskaźnika

2017-03-12 00:43

Rejestracja: 14 lat temu

Ostatnio: 1 tydzień temu

0
RS := TResourceStream.Create(HInstance,'data', RT_RCDATA);
RS.Read(RS_przes^,rs.Size);

Ten kawałek ładuje dane bezposrednio do zarezerowanej wczesniej pamięci. Jak wczytac te same dane z przesunięciem np o 100 bajtów do tej samej pamięci

edytowany 3x, ostatnio: furious programming, 2017-03-12 22:46

Pozostało 580 znaków

2017-03-12 01:53
Moderator Delphi/Pascal

Rejestracja: 8 lat temu

Ostatnio: 2 minuty temu

Lokalizacja: Tuchów

0
RS.Read(Pointer(RS_przes + 100)^, RS.Size);

lub inaczej:

Inc(RS_przes, 100);
RS.Read(RS_przes^, RS.Size);

O to chodzi? Jeśli nie to wytłumacz dokładniej.


edytowany 3x, ostatnio: furious programming, 2017-03-12 22:47

Pozostało 580 znaków

2017-03-12 10:05

Rejestracja: 14 lat temu

Ostatnio: 1 tydzień temu

0
var   Identyfikator1 :THandle;
      AdresE1 :pointer;

Function EdytorActivPointer:Pointer;
Begin
   EdytorActivPointer:=adresE1;
End;

Procedure x;
Var
    RS : TResourceStream;
Begin

  Identyfikator1:=GlobalAlloc(gmem_Fixed+gmem_ZeroInit,$02000000);
  AdresE1:=GlobalLock(Identyfikator1);

  RS := TResourceStream.Create(HInstance,'PLIK', RT_RCDATA);

  //Chodzi mi o to żeby do zarezerwowanej pamięci z pod wskażnika AdresE1 wgrać dane z plik do pamięci z przesunieciem 100 bajtów

  RS.Read(EdytorActivPointer^,rs.Size);

End;
edytowany 1x, ostatnio: furious programming, 2017-03-12 12:35

Pozostało 580 znaków

2017-03-12 12:43
Moderator Delphi/Pascal

Rejestracja: 8 lat temu

Ostatnio: 2 minuty temu

Lokalizacja: Tuchów

0

Byle jak opisujesz problem, to i trudno zrozumieć co masz na myśli.

Jak dobrze rozumiem, masz wskaźnik AdresE1 i do niego chcesz wczytać porcję danych. Dane te mają zostać wczytane ze strumienia RS. I teraz Ty potrzebujesz wczytać dane z tego strumienia, ale nie od jego początku, a najpierw przesunąć kursor o 100 i dopiero wtedy wczytać. Racja?

Jeśli tak to skorzystaj z właściwości RS.Position i wpisz do niej wartość 100 - kursor (inaczej mówiąc wskaźnik) w strumieniu zostanie przesunięty na bajt o indeksie 100 (licząc od 0), dzięki czemu metoda RS.Read rozpocznie odczytywanie porcji danych właśnie od tego bajtu. Skoro dane nie będą czytane od początku strumienia to w drugim parametrze trzeba to uwzględnić i odjąć liczbę pomijanych bajtów.

const
  STREAM_OFFSET = 100;

{..}

RS := TResourceStream.Create(hInstance, 'PLIK', RT_RCDATA);

RS.Position := STREAM_OFFSET;
RS.Read(EdytorActivPointer()^, RS.Size - STREAM_OFFSET);

Przy okazji - nazwij te zmienne sensownie. RS to zły identyfikator, a EdytorActivPointer ma błąd, bo słówko Active pisze się z e na końcu.


edytowany 8x, ostatnio: furious programming, 2017-03-12 18:34

Pozostało 580 znaków

2017-03-12 20:49

Rejestracja: 14 lat temu

Ostatnio: 1 tydzień temu

0

Mi chodzi nie o przesunięcie strumienia a gdzie dane będą już zapisane czyli w pamięci nie od pierwszego bajtu tylko z przesunięciem.

Pozostało 580 znaków

2017-03-12 20:53
Moderator Delphi/Pascal

Rejestracja: 8 lat temu

Ostatnio: 2 minuty temu

Lokalizacja: Tuchów

0

Podałem to w pierwszym swoim poście.


Pozostało 580 znaków

2017-03-12 21:38

Rejestracja: 14 lat temu

Ostatnio: 1 tydzień temu

0

Nie działa tak podczas komilaci mam błedy.

tak na początku miałem i chodziło ale bufor był ładowany od pierwszego bajtu

RS.Read(RS_przes^, RS.Size);

i chodziło dobrze, ale ładuje plik od początku pamięci

Po zamianie na :

Inc(RS_przes, 100);   // błąd: ordinal type required
RS.Read(RS_przes, RS.Size);  // bład operand not applicable to this operand type
edytowany 2x, ostatnio: furious programming, 2017-03-12 21:48

Pozostało 580 znaków

2017-03-12 21:50
Moderator Delphi/Pascal

Rejestracja: 8 lat temu

Ostatnio: 2 minuty temu

Lokalizacja: Tuchów

0
Inc(RS_przes, 100);   // błąd: ordinal type required

Jakiego typu jest to RS_przes?

RS.Read(RS_przes, RS.Size);  // bład operand not applicable to this operand type

Brakuje operatora ^.


edytowany 1x, ostatnio: furious programming, 2017-03-12 21:50

Pozostało 580 znaków

2017-03-12 22:01

Rejestracja: 14 lat temu

Ostatnio: 1 tydzień temu

0
  RS_przes:Pointer;  

 Inc(RS_przes^, 100);  jak do tego dorzuce ^ to mam błąd //incompatybile types
 RS.Read(RS_przes^, RS.Size); bo tu jest dobrze

Pozostało 580 znaków

2017-03-12 22:24
Moderator Delphi/Pascal

Rejestracja: 8 lat temu

Ostatnio: 2 minuty temu

Lokalizacja: Tuchów

0
Inc(RS_przes^, 100);  // jak do tego dorzuce ^ to mam błąd incompatybile types

Dziwisz się? Nie wstawiaj na pałę operatorów - myśl co robisz. W pierwszym parametrze Inc masz podać wskaźnik, a nie zawartość na którą wskazuje (której i tak w tym przypadku typ nie jest znany).


No dobra, mały przykład, co prawda testowany w Lazarusie, ale także z dyrektywą {$mode delphi}:

const
  SOME_STRING = 'furious'#0'programming'#0;
var
  L1stWord: Pointer;
  L2ndWord: Pointer;
begin
  L1stWord := @SOME_STRING[1];
  L2ndWord := @SOME_STRING[9];

  WriteLn('"', PChar(L1stWord), '"');
  WriteLn('"', PChar(L2ndWord), '"');

  WriteLn('"', PChar(L1stWord + 8), '"');  // z przesunięciem dodatnim o 8 bajtów
  WriteLn('"', PChar(L2ndWord - 8), '"');  // z przesunięciem ujemnym o 8 bajtów
end.

Zadanie programu jest proste - wyświetlić to na co wskazują dwa wskaźniki:

  • L1stWord - wskazuje na słówko furious,
  • L2ndWord - wskazuje na słówko programming.

Na ekranie konsoli zobaczymy to:

"furious"
"programming"
"programming"
"furious"

I teraz najważniejsze - co się dzieje w wywołaniach Writeln, są cztery:

  1. wyświetlenie zawartości wskazywanej przez L1stWord - wskaźnik zawiera adres pierwszego znaku pierwszego słowa, więc wyświetlane jest pierwsze słowo (słowo, bo do wystąpienia znaku NULL),
  2. wyświetlenie zawartości wskazywanej przez L2ndWord - wskaźnik zawiera adres pierwszego znaku drugiego słowa, więc wyświetlane jest drugie słówki,
  3. wyświetlenie ciągu na podstawie wskaźnika L1stWord i dodaniego przesunięcia o 8 bajtów - osiem bajtów dalej leży pierwszy znak drugiego słowa, więc ono zostaje wyświetlone,
  4. wyświetlenie ciągu na podstawie wskaźnika L2ndWord i ujemnego przesunięcia o 8 bajtów - osiem bajtów wcześniej leży pierwszy znak pierwszego słowa, więc ono zostaje wyświetlone.

Jak widzisz, w dwóch ostatnich wywołaniach obsługiwane są przesunięcia. Użyłem tutaj zwykłej arytmetyki, aby adresy zawarte w obu wskaźnikowych zmiennych nie uległy zmianie. Jeżeli zależy Ci na tym, aby zwiększyć adres w zmiennej to skorzystaj z Inc, która już od bardzo dawna wspiera wskaźniki.


edytowany 6x, ostatnio: furious programming, 2017-03-12 22:50

Pozostało 580 znaków

2017-03-12 22:38

Rejestracja: 14 lat temu

Ostatnio: 1 tydzień temu

0

no tak ale jak zrobie

Inc(RS_przes, 100);   // błąd: ordinal type required

to też mam bład

edytowany 1x, ostatnio: furious programming, 2017-03-12 22:43
Poza tym formatuj te posty jak należy - Formatowanie tekstu - furious programming 2017-03-12 22:44

Pozostało 580 znaków

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