Форум: "Начинающим";
Текущий архив: 2007.01.14;
Скачать: [xml.tar.bz2];
ВнизНе свитывается из файла JobInfo2W: Сначала я его записываю в файл Найти похожие ветки
← →
EgorovAlex © (2006-12-20 08:59) [0]А после считывании все поля с типом PWideChar равны nil. Это так и должно быть? Точно такие же действия работали в D7, а в Turbo Delphi все стринги обnilяются
← →
MBo © (2006-12-20 09:10) [1]А как ты записываешь и считываешь?
← →
EgorovAlex © (2006-12-20 09:37) [2]Записивыю в файл: здесь BytesNeed это размер, полученные из GetJob() при получении JobInfo2W
var
JobInfo2W: PJobInfo2W;
WriteFile(hFile, JobInfo2W^, BytesNeed, BytesWrite, nil);
Считываю:
ReadFile(hFile, JobInfo2W^, BytesNeed, BytesRead, nil);
В результате все стринговые поля =nil :(
← →
MBo © (2006-12-20 09:56) [3]>WriteFile(hFile, JobInfo2W^, BytesNeed, BytesWrite, nil);
Хм...
Получается, что ты в файл значение указателя (PWideChar) записываешь, а не данные строки
← →
EgorovAlex © (2006-12-20 10:01) [4]Нет, записывается не значение указателя, в D7 это работает и на запись и на считывание. Записывается и в TurboDelphi нормально (я содержимое файла вижу), вот только считывается странно
← →
Anatoly Podgoretsky © (2006-12-20 10:13) [5]> EgorovAlex (20.12.2006 10:01:04) [4]
Не указываешь объявления переменных.
Говоришь про чтение, а приводишь про запись.
← →
EgorovAlex © (2006-12-20 10:17) [6]Для считывания такой же тип:
var
JobInfo2W: PJobInfo2W;
GetMem(JobInfo2W, JobInfoSize);
ZeroMemory(JobInfo2W, JobInfoSize);
ReadFile(hFile, JobInfo2W^, JobInfoSize, BytesRead, nil);
JobInfoSize равен размеру JobInfo2W при записи
← →
Сергей М. © (2006-12-20 10:30) [7]
> записывается не значение указателя, в D7 это работает и
> на запись и на считывание
Ой ну врешь ведь)
в структуре JobInfo2W сплошные указатели на данные, а не сами данные:
_JOB_INFO_2W = record
JobId: DWORD;
pPrinterName: PWideChar;
pMachineName: PWideChar;
pUserName: PWideChar;
pDocument: PWideChar;
.. и т.д. ..
end;
← →
Сергей М. © (2006-12-20 10:31) [8]
> JobInfoSize равен размеру JobInfo2W при записи
И чему же он равен, по твоему ?
← →
Anatoly Podgoretsky © (2006-12-20 10:33) [9]> EgorovAlex (20.12.2006 10:17:06) [6]
Теперь бы узнать об загадочных строковых полях, увидеть бы обработку ошибок, а то ты очень самоуверен и узнать бы значения переменных до и после вызова.
← →
clickmaker © (2006-12-20 10:46) [10]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;
← →
Сергей М. © (2006-12-20 14:57) [11]
> clickmaker © (20.12.06 10:46) [10]
Ну дык ты те же самые указатели и засандалишь в файл ..
Или я не понял цели примера ?
← →
EgorovAlex © (2006-12-21 08:26) [12]Я использую именно такой код, как привёл 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-21 08:42) [13]Так. Поехали с начала.
Приведи сюда значения SizeOf(JobInfo2W^) для любого из заданий до и после вызова GetJob ...
← →
EgorovAlex © (2006-12-21 08:51) [14]А причём здесь SizeOf(JobInfo2W^)? Я же этот размер нигде не указываю и не использую. Пишется как в примере у clickmaker, там размер записи система даёт при вызове GetJob. Его и использую, данные все в файл пишутся, это видно в файле.
← →
MBo © (2006-12-21 09:05) [15]проверить мне не на чем, но есть такое предположение - GetJob получает буфер данных примерно в таком формате (если сохранится форматирование):
PJob->PWideChar1/PwideChar2...PwideChar3/ТелоСтроки1/ТелоСтроки2....
| ^
| |
--------------------------------------
Тогда при получении буфера указатели будут валидными и равны PJob+смещениеочереднойстроки
При записи в файл и чтении же эта взаимосвязь теряется
← →
Сергей М. © (2006-12-21 09:10) [16]
> причём здесь 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.
Как ты учитываешь это требование при чтении ?
← →
Сергей М. © (2006-12-21 09:11) [17]
> При записи в файл и чтении же эта взаимосвязь теряется
>
Совершенно верно !
← →
EgorovAlex © (2006-12-21 09:12) [18]У меня при записи сначала:
WriteFile(hFile, cbNeeded, SizeOf(cbNeeded), cbWritten);
потом
WriteFile(hFile, pJob^, cbNeeded, cbWritten);
А при чтении я сначала читаю JobInfoSize из файла, выделяю такой объём памяти и в него читаю остаток файла
← →
Сергей М. © (2006-12-21 09:15) [19]
> EgorovAlex © (21.12.06 09:12) [18]
Вот с этого и надо было начинать.
Тогда и вопросов к тебе было бы меньше.
Т.е. ты записал в файл указатели, которые после чтения во вновь выделенный тобой буфер попросту недействительны.
← →
EgorovAlex © (2006-12-21 09:27) [20]А как мне тогда лучше делать, чтобы сначала сохранить JobInfo, а потом считать?
И почему такой код всегда нормально работал в D7, а в Turbo работает не всегда?
← →
Сергей М. © (2006-12-21 09:35) [21]
> почему такой код всегда нормально работал в D7, а в Turbo
> работает не всегда?
Он мог и в D7 ненормально сработать, просто в тот момент звезды удачно расположились)
Следы ведут к отличиям в менеджерах памяти у D и TD.
> как мне тогда лучше делать, чтобы сначала сохранить JobInfo,
> а потом считать?
Перед записью менять в структуре значения полей указ.типа, делая замену VA -> RVA, т.е. записывая вместо абс.адреса строки ее смещение отн-но адреса начала буфера.
После чтения выполнять обратное преобразование RVA -> VA.
← →
Сергей М. © (2006-12-21 09:55) [22]что-то вроде этого:
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;
← →
EgorovAlex © (2006-12-21 09:56) [23]А как такую подмену сделать? Ни разу с таким не сталкивался
← →
EgorovAlex © (2006-12-21 09:56) [24]О спасибо, попробую, не заметил второго ответа
← →
EgorovAlex © (2006-12-21 10:12) [25]Спасибо, теперь всё работает!
← →
Сергей М. © (2006-12-21 11:11) [26]
> теперь всё работает
А куда оно денется с подводной лодки !)
Тем не менее остается невыясненным, почему у тебя
> после считывании все поля с типом PWideChar равны nil
Если ты записал заведомо не nil, то заведомо не nil и прочитаешь после этого.
← →
EgorovAlex © (2006-12-21 13:23) [27]Ну насчёт nil я наврал, там "" т.е. пустая строка, но иногда и нормальный текст возвращался
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2007.01.14;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.014 c