Форум: "Основная";
Текущий архив: 2004.02.06;
Скачать: [xml.tar.bz2];
ВнизПередача длинных строк PChar в dll. Найти похожие ветки
← →
Сергей В. (2004-01-22 20:47) [0]Здравствуйте! Моя программа передает большую строку типа PChar в dll,
затем шифрует ее и возвращает зашифрованную.
function EncryptString(const S, Password: PChar; var StrLength: LongWord): PChar; stdcall;
var
str: string;
pass: string;
I: Integer;
Res:string;
begin
str:="";
Setlength(str, StrLength);
Move(S^, str[1], StrLength);
Pass:="";
Pass:=string (Password);
Res:="";
if Length(Pass) > 0 then
for I := 1 to Length(str) do
Res:=Res+ Chr(Byte(pass[1 + ((I - 1) mod Length(pass))]) xor Ord(str[I]));
Result:=PChar (Res);
end;
При передаче больших строк типа Pchar (более 50-100 кб) возвращается
какое-то непонятное значение, которое не удается конвертировать назад
в string. К примеру:
P:=EncryptString...
P[0] вызывает access violation. Какие здесь могут быть подводные
камни?
← →
VMcL (2004-01-22 21:26) [1]uses ShareMem?
← →
Юрий Федоров (2004-01-22 21:31) [2]Как-то криво все...
Кто будет освобождать Result?
← →
Islander (2004-01-22 21:44) [3]А зачем освобождать Result?! Тогда же ничего не передастся назад, имхо
← →
Юрий Федоров (2004-01-22 21:57) [4]>>Result:=PChar (Res);
Автору
var
>>Res:string;
...
>>Result:=PChar (Res);
освободится по выходу из процедуры EncryptString
то, что ты в каких-то случаях считываешь нормальные значения - это тебе просто повезло, точнее НЕ повезло
Определись с тем, кто выделяет, а кто освобождает память, если разные модули(под модулем понимается exe или dll ), то без ShareMem не обойтись
Setlength(str, StrLength);
Move(S^, str[1], StrLength);
почему не написать
str:=S;
???
Pass:="";
Pass:=string (Password);
никогда на Hints и Warnings не обращаешь внимания ? А зря
pass:=Password;
на самом деле не нужно переприсваивать переданные параметры локальным переменным, лучше работать прямо с ними
← →
Юрий Федоров (2004-01-22 21:59) [5]StrLength не нужен, длину можно считать прямо с PChar
← →
Ломброзо (2004-01-22 22:11) [6]не смотрели, как объявляются функции, работающие с ASCIIZ строками, в WinSDK help? если нет - спешу уведомить, что таковой способ, каким пытаетесь вернуть указатель Вы, там нигде не встречается.
WINOLEAPI StringFromCLSID(REFCLSID rclsid, LPOLESTR * ppsz);
Перепишите-ка её лучше вот примерно так:
function EncryptString(const S, Password: PChar; AResult: PChar): boolean;
здесь Вы должны предварительно выделить память под AResult, Вы же её и должны освобождать. Если не хотите её выделять, а хотите, чтобы это сделала DLL, AResult должен быть указателем на указатель на char (как в примере StringFromCLSID - вызывающая сторона непременно должна будет вызвать CoTaskMemFree для освобождения ppsz).
А ещё лучше не портите нервы себе и окружающим и напейшите COM-dll c параметром BSTR/WideString.
← →
YuRock (2004-01-22 22:17) [7]Можно выделять память для PChar"a через GlobalAlloc и удалять ч-з GlobalFree - тогда не будет проблем и не нужны будут никакие ShareMem...
← →
Ломброзо (2004-01-22 22:21) [8]память мойшно выделять, навскидку, пятью-десятью способами - каким заблагорассудится... только понимать надо, что делаешь.
← →
YuRock (2004-01-23 16:34) [9]> Ломброзо © (22.01.04 22:21) [8]
> только понимать надо, что делаешь
Истину говоришь! Жаль, не скромно...
← →
YuRock (2004-01-23 16:34) [10]> Ломброзо © (22.01.04 22:21) [8]
> только понимать надо, что делаешь
Истину говоришь! Жаль, не скромно...
← →
Maksss (2004-01-23 16:36) [11]Result := AllocMem(Length(res)+1);
move(res[1],Result^,Length(res));
вот так работает
добрые люди тут подсказали ))
← →
Maksss (2004-01-23 16:45) [12]procedure TForm1.Button2Click(Sender: TObject);
var
hDL :THandle;
i : integer;
s,s1 : string;
sp,sp1 :pchar;
begin
sp := EncryptString(s1,sp1,i);
SetLength(s,i);
Move(sp^,s[1],i);
в s твой результат
в i должна быть длина(заполняется в длл)
end;
← →
panov (2004-01-23 17:04) [13]http://delphimaster.net/view/1-1074375281/
← →
Islander (2004-01-23 17:32) [14]> http://delphimaster.net/view/1-1074375281/
Супер!
← →
Сергей В. (2004-01-23 19:05) [15]Спасибо за http://delphimaster.net/view/1-1074375281/.
Но возникла другая прабла. Если функция в плагине немного другая.
function EncryptString(const S, Password: PChar; var StrLength: LongWord): PChar; stdcall;
var
str: string;
begin
Setlength(str, StrLength);
Move(S^, str[1], StrLength);
// какие действия с str...
StrLength := Length(str);
Result := AllocMem(StrLength+1);
move(str[1],Result^, Length(str));
end;
То при вызове FreeMem из программы происходит Invalid pointer
operation.
Не подскажите что не так?
← →
panov (2004-01-23 19:17) [16]Ты не показал, как в программе работаешь с функцией, как память освобождаешь.
← →
Сергей В. (2004-01-23 19:23) [17]Вот функция из программы.
function EncryptStringE(const S, Password, PluginName: string): string;
var
SourceLength : LongWord;
p : PChar;
LibHandle : THandle; // plugin handle
EncryptString : function (const S, Password: PChar;
var StrLength: LongWord): PChar; stdcall;
begin
// clear pointer
@EncryptString := nil;
// loading plugin
LibHandle:=LoadLibrary(PChar(AppPath + CryptPluginPath + PluginName));
if LibHandle >= 32 then
begin
@EncryptString := GetProcAddress(LibHandle, "EncryptString");
end;
SourceLength := Length(S);
if @EncryptString <> nil then
begin
p := EncryptString(PChar(S), PChar(Password), SourceLength);
SetLength(Result, SourceLength);
Move(p^, Result[1], SourceLength);
FreeMem(p);
end;
FreeLibrary(LibHandle);
end;
← →
Serginio666 (2004-01-23 19:25) [18]См
YuRock © (22.01.04 22:17) [7]
← →
Serginio666 (2004-01-23 19:33) [19]Все таки почитай на досуге http://www.rsdn.ru/article/Delphi/memmanager.xml
← →
Сергей В. (2004-01-23 19:56) [20]Проблема в том, что заранее не известна длина, которую вернет dll.
← →
YuRock (2004-01-23 20:59) [21]> Сергей В. (23.01.04 19:56) [20]
Если выделять память для строки через GlobalAlloc - то проблемы нет. Есть ф-ция GlobalSize
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2004.02.06;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.025 c