![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Не свитывается из файла JobInfo2W: Сначала я его записываю в файл
EgorovAlex © (2006-12-20 08:59:00)А после считывании все поля с типом PWideChar равны nil. Это так и должно быть? Точно такие же действия работали в D7, а в Turbo Delphi все стринги об nilяются
EgorovAlex (2006-12-21 13:23:00) [1]Ну насчёт nil я наврал, там '' т.е. пустая строка, но иногда и нормальный текст возвращался
Сергей М. (2006-12-21 11:11:00) [2]
> теперь всё работает
А куда оно денется с подводной лодки !)
Тем не менее остается невыясненным, почему у тебя
> после считывании все поля с типом PWideChar равны nil
Если ты записал заведомо не nil, то заведомо не nil и прочитаешь после этого.
EgorovAlex (2006-12-21 10:12:00) [3]Спасибо, теперь всё работает!
EgorovAlex (2006-12-21 09:56:00) [4]О спасибо, попробую, не заметил второго ответа
EgorovAlex (2006-12-21 09:56:00) [5]А как такую подмену сделать? Ни разу с таким не сталкивался
Сергей М. (2006-12-21 09:55:00) [6]что-то вроде этого:
var
p: PPointer;
..
VA->RVA :
p := @pJob.pPrinterName;
while p <> @pJob.pSecurityDescriptor do begin
p^ := Pointer(Cardinal(p^) - Cardinal(pJob));
Inc(p);
end;
RVA->VA :
p := @pJob.pPrinterName;
while p <> @pJob.pSecurityDescriptor do begin
p^ := Pointer(Cardinal(p^) + Cardinal(pJob));
Inc(p);
end;
Сергей М. (2006-12-21 09:35:00) [7]
> почему такой код всегда нормально работал в D7, а в Turbo
> работает не всегда?
Он мог и в D7 ненормально сработать, просто в тот момент звезды удачно расположились)
Следы ведут к отличиям в менеджерах памяти у D и TD.
> как мне тогда лучше делать, чтобы сначала сохранить JobInfo,
> а потом считать?
Перед записью менять в структуре значения полей указ.типа, делая замену VA -> RVA, т.е. записывая вместо абс.адреса строки ее смещение отн-но адреса начала буфера.
После чтения выполнять обратное преобразование RVA -> VA.
EgorovAlex (2006-12-21 09:27:00) [8]А как мне тогда лучше делать, чтобы сначала сохранить JobInfo, а потом считать?
И почему такой код всегда нормально работал в D7, а в Turbo работает не всегда?
Сергей М. (2006-12-21 09:15:00) [9]
> EgorovAlex © (21.12.06 09:12) [18]
Вот с этого и надо было начинать.
Тогда и вопросов к тебе было бы меньше.
Т.е. ты записал в файл указатели, которые после чтения во вновь выделенный тобой буфер попросту недействительны.
EgorovAlex (2006-12-21 09:12:00) [10]У меня при записи сначала:
WriteFile(hFile, cbNeeded, SizeOf(cbNeeded), cbWritten);
потом
WriteFile(hFile, pJob^, cbNeeded, cbWritten);
А при чтении я сначала читаю JobInfoSize из файла, выделяю такой объём памяти и в него читаю остаток файла
Сергей М. (2006-12-21 09:11:00) [11]
> При записи в файл и чтении же эта взаимосвязь теряется
>
Совершенно верно !
Сергей М. (2006-12-21 09:10:00) [12]
> причём здесь SizeOf(JobInfo2W^)?
Притом что он постоянен в любой момент времени внезависимости от чего-либо.
> Я же этот размер нигде не указываю и не использую
Тогда чему у тебя равен JobInfoSize ?
Ты вообще штудировал msdn перед тем как экспериментировать ?
Вот цитата:
pJob
[out] Pointer to a buffer that receives a JOB_INFO_1 or a JOB_INFO_2 structure containing information about the job. The buffer must be large enough to store the strings pointed to by the structure members.
Как ты учитываешь это требование при чтении ?
MBo (2006-12-21 09:05:00) [13]проверить мне не на чем, но есть такое предположение - GetJob получает буфер данных примерно в таком формате (если сохранится форматирование):
PJob->PWideChar1/PwideChar2...PwideChar3/ТелоСтроки1/ТелоСтроки2....
| ^
| |
--------------------------------------
Тогда при получении буфера указатели будут валидными и равны PJob+смещениеочереднойстроки
При записи в файл и чтении же эта взаимосвязь теряется
EgorovAlex (2006-12-21 08:51:00) [14]А причём здесь SizeOf(JobInfo2W^)? Я же этот размер нигде не указываю и не использую. Пишется как в примере у clickmaker, там размер записи система даёт при вызове GetJob. Его и использую, данные все в файл пишутся, это видно в файле.
Сергей М. (2006-12-21 08:42:00) [15]Так. Поехали с начала.
Приведи сюда значения SizeOf(JobInfo2W^) для любого из заданий дои послевызова GetJob ...
EgorovAlex (2006-12-21 08:26:00) [16]Я использую именно такой код, как привёл clickmaker. При этом в файл пишутся не указатели, а именно строки! Это можно посмотреть в hex editore. А вот на чтение этого файла возникают проблемы, или так работать нельзя? Тогда как сохранять правильно эти данные?
> var
> pJob: PJobInfo2W;
> bRes := GetJob(hPrinter, JobId, 2, pJob, 0, cbNeeded);
> if (bRes = False) and (GetLastError() = ERROR_INSUFFICIENT_BUFFER)
> then begin
> GetMem(pJob, cbNeeded);
> bRes := GetJob(hPrinter, JobId, 2, pJob, cbNeeded, cbNeeded);
>
> if (bRes)
> WriteFile(hFile, pJob^, cbNeeded, cbWritten);
> end;
Только у меня перед WriteFile(hFile, pJob^, cbNeeded, cbWritten);
пишется WriteFile(hFile, cbNeeded, SizeOf(cbNeeded), cbWritten);
Читаю так:
Сначала свитываю записанный размер, выделяю такого размера блок памяти и в него читаю данные из файла
Сергей М. (2006-12-20 14:57:00) [17]
> clickmaker © (20.12.06 10:46) [10]
Ну дык ты те же самые указатели и засандалишь в файл ..
Или я не понял цели примера ?
clickmaker (2006-12-20 10:46:00) [18]var
pJob: PJobInfo2W;
bRes := GetJob(hPrinter, JobId, 2, pJob, 0, cbNeeded);
if (bRes = False) and (GetLastError() = ERROR_INSUFFICIENT_BUFFER)
then begin
GetMem(pJob, cbNeeded);
bRes := GetJob(hPrinter, JobId, 2, pJob, cbNeeded, cbNeeded);
if (bRes)
WriteFile(hFile, pJob^, cbNeeded, cbWritten);
end;
Anatoly Podgoretsky (2006-12-20 10:33:00) [19]> EgorovAlex (20.12.2006 10:17:06) [6]
Теперь бы узнать об загадочных строковых полях, увидеть бы обработку ошибок, а то ты очень самоуверен и узнать бы значения переменных до и после вызова.
Сергей М. (2006-12-20 10:31:00) [20]
> JobInfoSize равен размеру JobInfo2W при записи
И чему же он равен, по твоему ?