Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.02.06;
Скачать: CL | DM;

Вниз

Передача длинных строк 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;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.018 c
6-16571
Эдик
2003-11-20 18:18
2004.02.06
ClientSocket и клиент microsoft


3-16129
PCLS
2004-01-13 14:58
2004.02.06
Клиент-сервер


14-16644
}|{yk
2004-01-13 13:02
2004.02.06
Смотрите, как нужно работать!


14-16738
Akvilon
2004-01-12 22:19
2004.02.06
На чем написана Delphi?


1-16242
New
2004-01-26 13:04
2004.02.06
Удаление файла