Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Не свитывается из файла JobInfo2W: Сначала я его записываю в файл


Страницы:   1 2

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 при записи


И чему же он равен, по твоему ?


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо