Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
9-16025
alexus
2003-07-22 10:53
2004.02.06
Алгоритм игры Го


14-16702
Knight
2004-01-17 00:02
2004.02.06
Какой виртуальный СД, создайт имиджи с расширением CDI ?


1-16264
MakNik
2004-01-26 09:58
2004.02.06
TEDIT


1-16458
HES
2004-01-27 11:18
2004.02.06
Как сделать задержку выполнения программы на N милисекунд?


1-16484
Oleg
2004-01-27 16:13
2004.02.06
Сохранение рисунков в dll





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский