Wczytywanie tablic z rekordu

0

Witam,
od pewnego czasu męczę się z odczytem recordu wysłanego przez clienta (napisanym w WinSock), do serwera. Record wygląda tak:

type
  TMsgType = (WelcomeMsg, LogonMsg, CommandMsg, ReturnMsg);

type
  TMessageRec = record
   _MsgType:TMsgType;
   _Msg:array of String;
   _LengthMsg:Byte;
end;

Serwer odczytuje record tak:

var
 Buff:TMessageRec;

[...]

 recv(Sock, Buff, SizeOf(TMessageRec), 0);

Parametry _LengthMsg, _MsgType są takie jak wysłał klient (u serwera).
Gdy próbuje odwołac się do tablicy dostaję accessa. Np.

       if (Buff._Msg[0]='blabla') then
         [...]

Sam record w kliencie wysyłam tym sposobem:

var
 MsgSend:TMessageRec;
begin
  MsgSend._MsgType:=LogonMsg;
  SetLength(MsgSend._Msg,3);
  MsgSend._LengthMsg:=3;
  MsgSend._Msg[0]:='1';
  MsgSend._Msg[1]:='2';
  MsgSend._Msg[2]:='3';
  send(Sock, MsgSend, SizeOf(TMessageRec), 0);

No i mam nadzieję, że co potrzebne napisałem.. Proszę o pomoc w odwoływaniu się do tablicy odebranego recordu..

0

nie możesz tak przesyłać ani tablic dynamicznych, ani stringów.
musisz każdy z tych elementów przesłać osobno, w specjalny sposób. a to z tego powodu, że wewnątrz rekordu tkwi tylko wskaźnik (4B) do obszaru pamięci zawierającego zawartość tablicy, a pod każdym elementem tablicy siedzi wskaźnik do pamięci zawierającej długość i ciąg znaków stringa. czyli zamiast zawartości tablicy wysyłasz adres czegoś, do czego odbiorca nie ma dostępu.
możesz to rozwiązać stosując tablicę o statycznej długości i stringi o długości < 256. jest to łatwe, ale kiepskie rozwiązanie.

0

Dobra, dzięki :)
Record zmieniłem na:

type
  TMessageRec = record
   _MsgType:TMsgType;
   _Msg:array[0..5] of String[255];
   _LengthMsg:Byte;
end;

i smiga :) Fakt faktem, że nie jest to najlepsze rozwiązanie, ale wydaje mi się, że do mojego programu te rozwiązanie będzie ok.

Jeszcze jedno pytanie lamerskie..
Jak wysłac:

DEF_LoginOk = $2;

funkcją send, bo robie tak:

send(Sock, Pointer(DEF_NotIn)^, SizeOf(Integer), 0);

Bo wiadomosc nie dochodzi do adresata tym sposobem.

0

send(Sock, DEF_NotIn, SizeOf(Integer), 0);

0

Myślisz, że tak nie próbowałem?

[Error] Constant object cannot be passed as var parameter

0

pointer($2) zwraca wskaźnik na adres $0:$2. pointer($2)^ zwraca to, co siedzi pod takim adresem, czyli tablicę wektorów przerwań, o ile tylko cudownym zrządzeniem losu dostaniesz uprawnienia do odczytu tego kawałka pamięci. zakładam, że wolisz jednak wysłać 2 niż wywoływać AV? jeśli tak, to po prostu stwórz zmienną buf dowolnego typu, najwygodniej tutaj - integer, przypisz do niej dwójkę i użyj tej zmiennej jako drugiego parametru funkcji send.
BTW - skąd wiesz, że DEF_NotIn ma rozmiar integera (SizeOf(Integer))? przecież to może być byte albo word - nie definiujesz typu przy tworzeniu tej stałej...

a na przyszłość - czytaj komunikaty o błędach ze zrozumieniem (F1).

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