Frohe Weihnachten allerseits
Ich arbeite gerade zum Spass an einem mittelmäßigen Chatprogramm für Delphi, was bisher auch relativ zügig voran ging, aber jetzt scheitert es an einem ziemlich nervigen (weil eigentlich nicht komplizierten) Problem....Zeiger....
Kann mir da evtl. jemand etwas unter die Arme greifen?
In der Haupt-
Unit sind nämlich u.A. folgende Typen und Variablen definiert:
Delphi-Quellcode:
type
{TCchatMessage - Träger für alle Art von Datenpacketen, die zwischen Client und Server verschickt werden}
TChatMessage = record
MsgType : Byte;
MsgContent : array[0..1023] of char;
end;
{TChatRoom - Ein Element innerhalb der Chatroomsm ObjectList}
TChatroom = class(TObject)
ClientsInRoom : TList;
Name : String[30];
end;
PChatroom = ^TChatroom;
{TChatRoom - Virtuelle Entsprechung eines Chat-Benutzers und Element der AllClients ObejectList}
TChatClient = class(TObject)
Nickname : String[15];
IPAddr : String[16];
Room : PChatroom;
Hash, awaymsg, dndmsg, abouttext : String;
BannedFromRooms, IgnoredClients : TStrings;
HasIdentified, IsAdmin: Boolean;
Status : TClientstatus;
Thread : PIDPeerThread;
end;
PChatClient = ^TChatClient;
var
Form1: TForm1;
MsgQueue, AllClients, BanList, Chatrooms: TObjectList;
//In diesen Listen werden die Chaträume, User usw. gespeichert und verwaltet
Das läuft dann so ab, dass Client und Server sich zuerst Hallo sagen, der Server einen neuen TChatClient in die Allclients Liste einfügt und dem Client dann einen Raum zuweist. Ein paar wichtige Funktionen, die das erledigen sehen so aus:
(die sind glaube ich nicht das Problem, aber glauben hilft ja nix :-/ )
Delphi-Quellcode:
function InitNewClient(
IP:
String; AThread: PIdPeerThread): TChatClient;
begin
Result := TChatClient.Create;
with Result
do
begin
Nickname :=
IP;
//temporär, Namenszuweisung erfolgt im nächsten Schritt
IPAddr :=
IP;
Hash := StringToHash(Nickname+IPAddr);
(** im Moment noch sinnlos...vielleicht später nützlich [Präadaption :P] **)
Room := AssignLobby;
//Sucht bzw. erzeugt die nächste nicht überfüllte Lobby
Room.ClientsInRoom.Add(@Result);
//ob das funtkioniert?
awaymsg := '
';
dndmsg := '
';
abouttext := '
';
BannedFromRooms := TStringlist.Create;
IgnoredClients := TStringlist.Create;
HasIdentified := false;
IsAdmin := false;
Status := csAvailable;
Thread := AThread;
end;
end;
function CreateRoom(designation:
string): TChatroom;
begin
Result := TChatroom.Create;
Result.
Name := designation;
Result.ClientsInRoom := TList.Create;
end;
function AssignLobby: PChatRoom;
var i: integer;
begin
//Untersuche Räume - Nächste Lobby die weniger als MaxUsersPerRoom User hat wird zurückgegeben
i := 1;
Result :=
nil;
While Result=nil
do
begin
Result := GetChatroomByName('
LOBBY-'+IntToStr(i));
Inc(i);
If Result =
nil then ChatRooms.Add(CreateRoom('
LOBBY-'+IntToStr(i)))
else
If Result.ClientsInRoom.Count<MaxUsersPerRoom
then
break;
end;
end;
Das klappt schon ganz ordentlich, nur eine Funktion zickt noch (kann mir aber nicht sicher sein, dass es die einzige ist) :
Delphi-Quellcode:
function GetChatroomByName(RoomName: String): PChatRoom;
var i: Integer;
begin
Result := nil;
for i:=0 to ChatRooms.Count-1 do
If (Chatrooms[i] as TChatroom).Name = RoomName then
begin
Result := Pointer( (Chatrooms.Items[i] as TChatRoom));
break;
end;
end;
Das Problem: Wenn ich diese Funktion aufrufe, gibt sie zwar einen gültigen Zeiger auf *irgendetwas* anderes als
nil zurück, allerdings erhalte ich nur "Datenmüll" bei folgendem Test:
ShowMessage(GetChatroomByName('LOBBY-1').Name);
---------------------------
IP Delphi Chat
---------------------------
m‹À¼ÒJ ( + sehr viele Leerzeichen)
---------------------------
OK
---------------------------
Ich hab schon verschiedene Dinge ausprobiert, da ich dachte es stimme etwas von der Logik her mit der GetChatroomByname Funktion nicht, aber eigentlich müsste sie ja das richtige Ergebnis liefern, oder?
Viele Grüße an alle
DP'ler und danke schonmal fürs lesen! Normalerweise versuche ich nicht unnötig auszuholen beim posten aber das hier ist schon etwas verzwickt
Dani H.