C++ to Delphi

Тема в разделе "WASM.WIN32", создана пользователем Searcher, 4 дек 2004.

  1. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    volodya > "Не, ну я уже злиться начинаю..."

    И правильно, меня так это просто бесит. И дело не в ереси, а в наглости, с какой человек, имея отдаленные представления и не желая самостоятельно разбираться в вопросе, хочет на халяву заполучить готовое решение.

    Что бум делать-то ? Пошлем "учиться, учиться и учиться" или окажем очередную медвежью услугу ?

    Ладно, поможем чем можем, надеюсь в последний раз.



    Searcher > "эти функции я переконвертил в дельфи"

    Ну-ну...

    Начнем "разбор полетов" с конца опуса - от больших глупостей к малым:

    1) Самая большая глупость - это копировать данные из одного файла в другой по одному байту, когда известен размер (а потом еще удивляться, что работает медленно). Ты, что сишный вариант копирования данных не можешь на паскале записать ? Заменить <font size=2>new -> GetMem, fread -> blockread, fwrite -> bkockwrite и delete -> FreeMem</font><!--size-->. Или разжевать и в рот положить:<font color="gray]
    Код (Text):
    1. var buf:pointer;
    2.   Rewrite(ToF,1);
    3.   GetMem(buf,rec[j].size);
    4.   blockread(FromF,buf^,rec[j].size); //!!! "крышечка" нужна, дружок, dereference называется
    5.   blockwrite(ToF,buf^,rec[j].size);
    6.   FreeMem(buf);
    7.   CloseFile(ToF);
    <font size=2>Пояснение насчет "крышечки", т.к. на этом многие начинающие попадаются. В BlockXXX передается var Buf, т.е. адрес того места памяти в которое будет производиться чтение. В нашем случае Buf это указатель на блок динамической памяти. Адрес самой переменной Buf - это адрес 4 байт в стеке, поэтому если подставить в blockXXX просто Buf, то ес-но при чтении мы загадим весь стек и в итоге получим ошибку. Если же мы берем Buf^, то получаем адрес блока динамической памяти, на которую ссылается стековая переменная Buf и все получается ОК.

    А вот варианты записи rec[j] и rec^[j] равноправны, здесь компилер понимает о чем идет речь (хотя для строгости лучше с крышкой).</font><!--size--></font><!--color-->



    2) Опус номер два: preFName делается копированием по байту из FName.

    Нормальные люди делают так preFName:=Copy(FName,1,Length(FName)-4).

    А в данном случае, это видимо имя файла без расширения, поэтому можно и надежнее так

    preFName:=ChangeFileExt(FName,'');



    3) А уж махинации с size - это какой-то маразм или извращение. IntToHex, HexToInt - для чего это ?

    Вся эта хрень в нормальном виде выглядит просто: blockread(FromF,rec^[j].size,4);



    4) Чтение имени файла. Ладно не хочешь писать размер строки в файл - дело твое.

    Но для чего BufName объявлять массивом и брать Char(BufName) ? Раз у тебя str - короткая строка, то ИМХО проще делать так:<font color="gray]
    Код (Text):
    1. var p:pChar;
    2.   str:='';
    3.   p:=@str;
    4.   repeat
    5.     inc(p);
    6.     blockread(FromF,p^,1); //читаем символ прямо в строку
    7.   until p^ = #0;
    8.   byte(str[0]):=p-pChar(@str[1]); //или SetLength(str,p-pChar(@str[1])
    </font><!--color-->И еще ВОПРОС: как объявлена строка rec[j].FPN - как динамическая string или короткая shortstring или string[x]. Если как короткая фиксированной длины, то можно писать символы прямо в нее (минуя str). Если же как динамическая, то в конце перед FreeMem(rec) нужно очистить все строки вызовом Finalize(rec^[1],CountFiles), иначе они так и останутся подвешенными в хипе;



    5) Каков в итоге у тебя тип PboEntry и что за тип rec:TRec ? Хоть бы потрудился привести описание. Судя по тому, что ты просто в начале делаешь GetMem и затем сразу пишешь в rec[j], то rec - это массив записей PboEntry, объявленных как record. А в начале вроде бы это было классом или нет ?