|
#1
|
|||
|
|||
ReadFile в потоке
День добрый.
Работаю с именованным каналом. Синхронный, блокирующий. Сервер ждет данных от клиента в отдельном потоке. Код:
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^ Вот. |
#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; Пишу программы за еду. __________________ |