Текущий архив: 2007.01.28;
Скачать: CL | DM;
Вниз
WinToDos & CopyFile Найти похожие ветки
← →
NovaC (2007-01-10 15:59) [0]Доброе время суток !
После выполнения function CopyFile
процедура WinToDos начинает выдавать какой-то мусор вместо нормальной строки.
CopyFile и WinToDos находятся в dll библиотеке
Причём если в function CopyFile происходит ошибка при IdFTP.Connect то
procedure WinToDos продолжает работать исправно!!!
Причём проблема появляется как с кирилицей так и с латинскими буквами
Помогите пожалуйста разобраться!!!
procedure WinToDos(const WinStr: pchar; var DosStr: pchar);
var
tmp2 : PChar;
begin
tmp2 := AllocMem(length(WinStr) + 1);
if CharToOem(PChar(WinStr),tmp2) then
DosStr := tmp2
else DosStr := "";
FreeMem(tmp2);
end;
function CopyFile (Copy{Put, Get}, Host, UserName, Password, FTPDir, SourceFile, PutFile : pchar) : boolean;
var
IdFTP : TIdFTP;
begin
result := false;
IdFTP := TIdFTP.Create(nil);
IdFTP.Host := pchar(Host);
IdFTP.UserName := pchar(UserName);
IdFTP.Password := pchar(Password);
try
if IdFTP.Connected = false
then IdFTP.Connect;
except
MessageDlg("Ошибка : IdFTP.Connect!",mtError, [mbOK],0);
IdFTP.Abort;
IdFTP.Free;
exit;
end;
if trim(FTPDir) <> "" then IdFTP.ChangeDir(FTPDir);
try
if trim(Copy) = "Put" then IdFTP.Put(SourceFile,PutFile,true);
if trim(Copy) = "Get" then IdFTP.Get(SourceFile,PutFile,true);
except
MessageDlg("Ошибка : IdFTP." + pchar(Copy) + "()!",mtError, [mbOK],0);
IdFTP.Abort;
IdFTP.Free;
exit;
end;
IdFTP.Disconnect;
IdFTP.Free;
result := true;
end;
Заранее спасибо за ответ . . .
← →
Desdechado © (2007-01-10 16:30) [1]
var DosStr: pchar
и что ж ты после этого хочешь?
tmp2 : PChar;
DosStr := tmp2;
FreeMem(tmp2);
возвращаешь указатель на освобожденный участок памяти
← →
NovaC (2007-01-11 05:47) [2]Desdechado, Спасибо за помощь,
Но почему без IdFTP.Put & IdFTP.Get всё работает?
После следующих изменений всё заработало,
но насколько это правильно?
procedure WinToDos(const WinStr: pchar; var DosStr: pchar);
var
tmp2 : PChar;
temp : string;
begin
tmp2 := AllocMem(length(WinStr) + 1);
if CharToOem(PChar(WinStr),tmp2) then
begin
temp := StrPas(tmp2);
DosStr := pchar(temp)
end
else DosStr := "";
FreeMem(tmp2);
end;
← →
ors_archangel © (2007-01-11 06:22) [3]А чем не нравится использовать строки:
function WinToDos(const WinStr: string): string;
var
len: integer;
begin
if WinStr="" then
result := ""
else begin
len := length(WinStr);
setlength(result, len + 1);
if not CharToOem(@WinStr[1],@result[1]) then result := "";
end;
end;
- будет быстрее работать.... Если WinStr,DosStr: pChar, то, конечно
DosStr := pChar(WinToDos(String(WinStr)));
но, конечно, можно и с PChar всё делать, но часто строки эффективнее по скорости
← →
NovaC (2007-01-11 06:39) [4]
> но, конечно, можно и с PChar всё делать, но часто строки
> эффективнее по скорости
pChar потому что процедура в dll библиотеке,
а в этом случае string не рекомендуют использовать
← →
ors_archangel © (2007-01-11 06:48) [5]Согласен, только замечу, что код [2] может вызывать утечки памяти, потому как, хотя ты очищаешь временную переменную - буфер для конверции, но StrPas его опять копирует (выделяет под него память), а так как приёмник - pChar, то сам он его никогда не очистить, другими словами, твои изменения в коде от [0] к [2] заключаются в том, что раньше ты выделял буфер, конвертировал в него и тут же освобождал его, что вызывало ошибки обращения к невыделенной памяти, теперь же ты дважды выделяешь буфер (один раз неявно) и один раз освобождаешь его, что ты делал и раньше, но теперь-то есть копия, поэтому обращения не будут ошибочными, но теперь тебе придётся пердусмостреть очитку данной перменной (DosStr). Есть правило: память нужно освобождать на том же уровне, где она выдеяется, это упрощает жизнь, т.е. если мы предварительно выделим буфер для DosStr нужной длины, то нам естественным образом захочется его самим же очистить и наоборот: если мы сами не выделяли этот буфер, а нам его выделил кто-то, то пусть он бы лучше сам о нём заботился, - это естественно. Как ты думаешь, почему все WinAPI функции всегда требуют предвыделенного буфера? Именно по этой причине.
← →
NovaC (2007-01-11 07:00) [6]Стало совсем не понятно зачем приводится много вариантов отдельных процедур типа WinToDos & DosToWin
когда есть CharToOem & OemToChar.
Я отказался от
procedure WinToDos(const WinStr: pchar; var DosStr: pchar);
которая у меня быля в dll библиотеке (поэтому и pChar, а не string)
и использую CharToOem в pas модуле - всё работает.
Может я чего-то недопонимаю
подскажите пожалуйста?
← →
NovaC (2007-01-11 08:48) [7]Работает, но не везде!!!
s : pchar;
m : string;
m := "";
s := pchar(m + "ля-ля-ля");
CharToOem(s,s);
если убрать "m" s := pchar("ля-ля-ля");
то на CharToOem(s,s); выскакивает ошибка!!!
В чём дело???
← →
Desdechado © (2007-01-11 10:54) [8]> если убрать "m" s := pchar("ля-ля-ля");
> то на CharToOem(s,s); выскакивает ошибка!!!
В том, что"ля-ля-ля"
- это константа, аm + "ля-ля-ля"
- нет.
Страницы: 1 вся ветка
Текущий архив: 2007.01.28;
Скачать: CL | DM;
Память: 0.47 MB
Время: 0.041 c