![]() |
|
|
#1
|
|||
|
|||
|
День добрый.
Работаю с именованным каналом. Синхронный, блокирующий. Сервер ждет данных от клиента в отдельном потоке. Код:
hNewHeap:=HeapCreate(HEAP_NO_SERIALIZE,SizeOfWaitingData,0);
Buffer:=HeapAlloc(hNewHeap,0,SizeOfWaitingData);
repeat
SuccessRead:=ReadFile(hPipe, buffer, SizeOfWaitingData, bytesRead, nil);
if not SuccessRead then begin
ShowMessage(_GetErrorMsg( GetLastError ));
break;
end;
Until false;По результату - всегда SuccessRead=false, с ошибкой "Неверная попытка доступа к адресу памяти". Замена на Код:
HeapAlloc(GetProcessHeap,0,SizeOfWaitingData); Помогает выделение буфера в стэке, вида: Код:
var bufferar:array[0..2000] of byte; но мне это не надо. Также нормально работает в основном потоке программы, но это мне тоже не надо. VurtualAlloc не пробовал пока. |
|
#2
|
|||
|
|||
|
SuccessRead:=ReadFile(hPipe, buffer^, SizeOfWaitingData, bytesRead, nil);
Второй параметр ReadFile - var Buffer; - безтиповая переменная. В случае, когда buffer - статический массив, то так передавать можно, var buffer:array[0..2000] of byte; адрес статического массива совпадает с адресом его первого элемента. В случае динамического массива, или когда var buffer:Pointer; адрес памяти и адрес самой переменной buffer - это две большие разницы. Поэтому нужно указывать не buffer, а разыменовать - buffer^ Вот. |
|
#3
|
||||
|
||||
|
На самом деле в обоих случаях достаточно передавать Buffer[0].
|
|
#4
|
||||
|
||||
|
подытожим:
Buffer: array [0..$ff] of Char Код:
var
hFile: THandle;
Buffer: array [0..$ff] of Char;
Dummy: DWORD;
begin
hFile:=CreateFile('Unit1.pas', GENERIC_READ, 0, nil, OPEN_EXISTING, 0, 0);
ReadFile(hFile,
Buffer[0],
$100,
Dummy, nil);
ShowMessage(Copy(Buffer, 1, Dummy));
CloseHandle(hFile);
end;Buffer: array of Char Код:
var
hFile: THandle;
Buffer: array of Char;
Dummy: DWORD;
begin
SetLength(Buffer, $100);
hFile:=CreateFile('Unit1.pas', GENERIC_READ, 0, nil, OPEN_EXISTING, 0, 0);
ReadFile(hFile,
Buffer[0],
$100,
Dummy, nil);
ShowMessage(Copy(String(@Buffer[0]), 1, Dummy));
CloseHandle(hFile);
end;Buffer: Pointer Код:
var
hFile: THandle;
Buffer: Pointer;
Dummy: DWORD;
begin
Buffer:=GetMemory($100);
hFile:=CreateFile('Unit1.pas', GENERIC_READ, 0, nil, OPEN_EXISTING, 0, 0);
ReadFile(hFile,
Buffer^,
$100,
Dummy, nil);
ShowMessage(Copy(PChar(Buffer), 1, Dummy));
CloseHandle(hFile);
FreeMemory(Buffer);
end;Buffer: String Код:
var
hFile: THandle;
Buffer: String;
Dummy: DWORD;
begin
SetLength(Buffer, $100);
hFile:=CreateFile('Unit1.pas', GENERIC_READ, 0, nil, OPEN_EXISTING, 0, 0);
ReadFile(hFile,
PChar(@Buffer[1])^,
$100,
Dummy, nil);
ShowMessage(Copy(Buffer, 1, Dummy));
CloseHandle(hFile);
end; |