C to Delphi: struct not 被填充
C to Delphi: Struct not is filled
我正在尝试将一段代码从 C 翻译成 Delphi,其目标是填充一个结构,直到先前定义的最大限制允许为止。我试着让 Delphi 版本更接近 C 代码(即使不是专业程序员)。
但我注意到,在我的 Delphi 代码中,seems 结构仅填充了 0 个值(FillMemory()
的结果),而没有填充正确的值。
我该如何解决?下面我只显示相关代码。
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;
您没有在 C 端或 Delphi 端显示实际尝试用数据填充数组的代码。查看原始 C 代码,它使用 ClientThread()
函数内的数据填充找到的数组元素。你没有翻译那些 C 代码,这就解释了为什么你的 Delphi 代码中的数组没有数据:
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;
}
无论如何,您的翻译接近于您显示的 C 代码,但不完全正确,特别是关于 Client
记录。您没有按照与 C 代码相同的顺序声明成员。而Delphi的Boolean
与C的BOOL
不是同一类型。 Delphi 的等价物是 LongBool
(Delphi 有 LongBool
的 BOOL
别名)。
试试这个:
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;
我正在尝试将一段代码从 C 翻译成 Delphi,其目标是填充一个结构,直到先前定义的最大限制允许为止。我试着让 Delphi 版本更接近 C 代码(即使不是专业程序员)。
但我注意到,在我的 Delphi 代码中,seems 结构仅填充了 0 个值(FillMemory()
的结果),而没有填充正确的值。
我该如何解决?下面我只显示相关代码。
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;
您没有在 C 端或 Delphi 端显示实际尝试用数据填充数组的代码。查看原始 C 代码,它使用 ClientThread()
函数内的数据填充找到的数组元素。你没有翻译那些 C 代码,这就解释了为什么你的 Delphi 代码中的数组没有数据:
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;
}
无论如何,您的翻译接近于您显示的 C 代码,但不完全正确,特别是关于 Client
记录。您没有按照与 C 代码相同的顺序声明成员。而Delphi的Boolean
与C的BOOL
不是同一类型。 Delphi 的等价物是 LongBool
(Delphi 有 LongBool
的 BOOL
别名)。
试试这个:
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;