FLASHCODER
FLASHCODER

Reputation: 294

C to Delphi: Struct not is filled

I'm trying translate a piece of code from C to Delphi, that have as goal fill a struct until max limit allowed previous defined. I tried make the Delphi version more near of C code (even so not be a professional programmer).

But i noted that in my Delphi code the seems struct is filled only with 0 values (result of FillMemory()) and not is being filled with correct values.

How i can solve it? below i show only the relevant code.

C: (code of reference)

struct Client
{
   SOCKET connections[2];
   DWORD  uhid;
   HWND   hWnd;
   BYTE  *pixels;
   DWORD  pixelsWidth, pixelsHeight;
   DWORD  screenWidth, screenHeight;
   HDC    hDcBmp;
   HANDLE minEvent;
   BOOL   fullScreen;
   RECT   windowedRect;
};

static Client g_clients[256];


static Client *GetClient(void *data, BOOL uhid)
{
   for(int i = 0; i < 256; ++i)
   {
      if(uhid)
      {
         if(g_clients[i].uhid == (DWORD) data)
            return &g_clients[i];
      }
      else
      {
         if(g_clients[i].hWnd == (HWND) data)
            return &g_clients[i];
      }
   }
   return NULL;
}

BOOL recordClient()
{
  Client *client = NULL;
  BOOL   found = FALSE;
  DWORD  uhid;


uhid = 27650; // Some value, only as example here
memset(g_clients, 0, sizeof(g_clients));

client = GetClient((void *) uhid, TRUE);

 if(client)
   return FALSE;

    for(int i = 0; i < 256; ++i)
    {
      if(!g_clients[i].hWnd)
      {
         found = TRUE;
         client = &g_clients[i];
      }
    }

    if(!found)
    {
      wprintf(TEXT("User %S kicked max %d users\n"), "185.242.4.203", 256);
      return FALSE;
    }

   return TRUE;
}

Delphi:

type
  PClient = ^Client;

  Client = record
    Connections: array [0 .. 1] of TSocket;
    uhId, 
    pixelsWidth, 
    pixelsHeight, 
    screenWidth, 
    screenHeight: Cardinal;
    _hWnd: HWND;
    Pixels: PByte;
    hDcBmp: HDC;
    minEvent: THandle;
    fullScreen: Boolean;
    windowRect: TRect;
  end;


var
  Clients: array [0 .. 255] of Client;

//...

function GetClient(Data: Pointer; uhId: Boolean): PClient;
var
  I: Integer;
begin
  Result := nil;
  for I := 0 to 255 do
  begin
    if uhId then
    begin
      if Clients[I].uhId = Cardinal(Data) then
      begin
        Result := @Clients[I];
        Break;
      end;
    end
    else
    begin
      if Clients[I]._hWnd = HWND(Data) then
      begin
        Result := @Clients[I];
        Break;
      end;
    end;
  end;
end;

function recordClient: Boolean;
var
  _client: PClient;
  _uhId: Cardinal;
  found: Boolean;
  I: Integer;
begin
  Result := True;

  FillMemory(@Clients, SizeOf(Clients), 0);

  _uhId := 27650; // Some value, only as example here
  _client := GetClient(@_uhId, True);

  if _client <> nil then
  begin
    Result := False;
    Exit;
  end;

  found := False;

  for I := 0 to 255 do
  begin
    if Clients[I]._hWnd = 0 then
    begin
      found := True;
      _client := @Clients[I];
    end;
  end;

  if not found then
  begin                                            
    Writeln(Format('Client %s rejected, max allowed is %d clients.' + #13,
      ['185.242.4.203', 256])); // Only example values
    Result := False;
    Exit;
  end;
end;

Upvotes: 0

Views: 92

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 595377

You have shown no code, on either the C side or the Delphi side, that actually tries to fill the array with data. Looking at the original C code, it populates a found array element with data inside of the ClientThread() function. You didn't translate those pieces of C code, which explains why the array in your Delphi code has no data in it:

static DWORD WINAPI ClientThread(PVOID param)
{
   Client    *client = NULL;
   SOCKET     s = (SOCKET) param;
   ...

   if(connection == Connection::desktop)
   {
      client = GetClient((void *) uhid, TRUE);
      if(!client)
      {
         closesocket(s);
         return 0;
      }
      client->connections[Connection::desktop] = s;

      ...

      for(;;)
      {
         ...

         if(recv(s, (char *) &client->screenWidth, sizeof(client->screenWidth), 0) <= 0)
            goto exit;
         if(recv(s, (char *) &client->screenHeight, sizeof(client->screenHeight), 0) <= 0)
            goto exit;
         ...

            if(client->pixels && client->pixelsWidth == ... && client->pixelsHeight == ...)
            {
               for(...)
               {
                  ...
                  client->pixels[i] = newPixels[i];
                  client->pixels[i + 1] = newPixels[i + 1];
                  client->pixels[i + 2] = newPixels[i + 2];
               }
               ...
            }
            else
            {
               free(client->pixels);
               client->pixels = newPixels;
            }

            ...
            DeleteDC(client->hDcBmp);
            client->pixelsWidth = width;
            client->pixelsHeight = height;
            client->hDcBmp = hDcBmp;

            ...
         }
         ...
      }
exit:
      ...
      return 0;
   }
   else if(connection == Connection::input)
   {
      ...

         client = GetClient((void *) uhid, TRUE);
         if(client)
         {
            closesocket(s);
            ...
            return 0;
         }
         ...

         BOOL found = FALSE;
         for(int i = 0; i < gc_maxClients; ++i)
         {
            if(!g_clients[i].hWnd)
            {
               found = TRUE;
               client = &g_clients[i];
            }
         }
         if(!found)
         {
            wprintf(TEXT("User %S kicked max %d users\n"), ip, gc_maxClients);
            closesocket(s);
            return 0;
         }

         client->hWnd = CW_Create(uhid, gc_minWindowWidth, gc_minWindowHeight);
         client->uhid = uhid;
         client->connections[Connection::input] = s;
         client->minEvent = CreateEventA(NULL, TRUE, FALSE, NULL);

      ...

         free(client->pixels);
         DeleteDC(client->hDcBmp);
         closesocket(client->connections[Connection::input]);
         closesocket(client->connections[Connection::desktop]);
         CloseHandle(client->minEvent);
         memset(client, 0, sizeof(*client)); 

      ...
   }
   return 0;
}

In any case, your translation is close to the C code you did show, but not entirely correct, particularly in regards to the Client record. You are not declaring the members in the same order that the C code does. And Delphi's Boolean is not the same type as C's BOOL. Delphi's equivalent is LongBool instead (Delphi has a BOOL alias for LongBool).

Try this instead:

type
  PClient = ^Client;
  Client = record
    Connections: array[0..1] of TSocket;
    uhId: DWORD;
    _hWnd: HWND;
    Pixels: PByte;
    pixelsWidth, pixelsHeight: DWORD;
    screenWidth, screenHeight: DWORD;
    hDcBmp: HDC;
    minEvent: THandle;
    fullScreen: BOOL;
    windowedRect: TRect;
  end;

var
  Clients: array[0..255] of Client;

function GetClient(Data: Pointer; uhId: Boolean): PClient;
var
  I: Integer;
begin
  for I := 0 to 255 do
  begin
    if uhId then
    begin
      if Clients[I].uhId = DWORD(Data) then
      begin
        Result := @Clients[I];
        Exit;
      end
      else
      begin
        if Clients[I]._hWnd = HWND(Data) then
        begin
          Result := @Clients[I];
          Exit;
        end;
      end;
    end;
  end;
  Result := nil;
end;

function recordClient: BOOL;
var
  _client: PClient;
  found: Boolean;
  uhId: DWORD;
  I: Integer;
begin
  ZeroMemory(@Clients, Sizeof(Clients));

  uhId := 27650; // Some value, only as example here
  _client := GetClient(Pointer(uhid), TRUE);

  if _client <> nil then
  begin
    Result := FALSE;
    Exit;
  end;

  found := False;

  for I := 0 to 255 do
  begin
    if Clients[i]._hWnd = 0 then
    begin
      found := True;
      _client := @Clients[i];
      Break;
    end;
  end;

  if not found then
  begin
    WriteLn(Format('Client %s rejected, max allowed is %d clients.', ['185.242.4.203', 256]));
    Result := FALSE;
    Exit;
  end;

  // TODO: populate _client here as needed...

  Result := TRUE;
end;

Upvotes: 1

Related Questions