Форум: "Основная";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.05.02;
Скачать: [xml.tar.bz2];




Вниз

dll + String +PChar 


OlegG   (2002-04-16 09:01) [0]

Здравствуйте, уважаемые мастера. Возникла следующая проблема:
Есть функция, криптующая строку, передаваемую параметром и возвращает строку в криптованом виде.
const
StartKey = 981;
MultKey = 12674;
AddKey = 35891;
function Encrypt(const InString: string; StartKey, MultKey, AddKey: Integer):string;
function Decrypt(const InString: string; StartKey, MultKey, AddKey: Integer):string;

var
....

implementation

{$R *.DFM}
{$R-}
{$Q-}
function Encrypt(const InString: string; StartKey,MultKey,AddKey: Integer): string;
var
i: Byte;
begin
Result:= "";
for i:= 1 to length(InString) do
begin
Result:= Result + CHAR(Byte(InString[i]) xor (StartKey shr 8));
StartKey:= (Byte(Result[i]) + StartKey)*MultKey + AddKey;
end;
end;
{$R+}
{$Q+}

Решил поместить ее в dll. Но при этом возникают проблемы с типом String (возвращаемое ф-цией). Советуют в качестве возвращаемого параметра использовать PChar. Но после конвертирования результата ф-цией PChar часть строки просто исчезает (очевидно там были пробелы). Естественно, что после декриптования получается только часть строки... В качестве наглядного примера можно передать параметром следующую строку: function Encrypt(const InString: string; StartKey, MultKey, AddKey: Integer):string; После декриптования получится только function Encr
Как быть? Заранее благодарен за советы...



MBo   (2002-04-16 09:10) [1]

Если используешь string в DLL, sharemem первым в uses надо ставить.
>очевидно там были пробелы
не пробелы, а нули #0
можно при кодировке при получении 0 заменять его на что-то другое и наоборот



OlegG   (2002-04-16 09:53) [2]

> MBo ©
sharemem не помогает...
Ругается у меня на FreeLibrary(LibHandle);
А сами ф-ции Encrypt и Decrypt отрабатывают правильно...
Если нужен код самой dll, то могу написать...

unit Unit1;

interface

uses
sharemem, Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ShellApi;

type
TForm1 = class(TForm)
Memo1: TMemo;
Memo2: TMemo;
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

const
StartKey = 981;
MultKey = 12674;
AddKey = 35891;


var
Form1: TForm1;
Encrypt : function (const InString: string; StartKey, MultKey, AddKey: Integer):string;
Decrypt : function (const InString: string; StartKey, MultKey, AddKey: Integer):string;
LibHandle : THandle;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
Memo1.Clear;
Memo2.Clear;
end;


procedure TForm1.Button1Click(Sender: TObject);
var
tmp : string;
begin
@Encrypt:= nil;
@Decrypt:= nil;
LibHandle:= LoadLibrary("crypt.dll");
if LibHandle >= 32 then
begin
@Encrypt:= GetProcAddress(LibHandle,"Encrypt");
@Decrypt:= GetProcAddress(LibHandle,"Decrypt");
if @Encrypt <> nil then
tmp:= Encrypt(Memo1.Text, StartKey, MultKey, AddKey);

if @Decrypt <> nil then
Memo2.Text:= Decrypt(tmp, StartKey, MultKey, AddKey);
end;
FreeLibrary(LibHandle);
end;

end.



MBo   (2002-04-16 10:11) [3]

в библиотеке тоже sharemem есть?



OlegG   (2002-04-16 10:17) [4]

Да, есть. Вот код библиотеки...
library crypt;

uses
sharemem,
SysUtils,
Classes;

{$R *.res}
{$R-}
{$Q-}
function Encrypt(const InString: string; StartKey,MultKey,AddKey: Integer): string;
var
i : Byte;
begin
for i:= 1 to length(InString) do
begin
Result:= Result + CHAR(Byte(InString[i]) xor (StartKey shr 8));
StartKey:= (Byte(Result[i]) + StartKey)*MultKey + AddKey;
end;
end;

function Decrypt(const InString: string; StartKey,MultKey,AddKey: Integer): string;
var
i : Byte;
begin
Result:= "";
for i:= 1 to length(InString) do
begin
Result:= Result + CHAR(Byte(InString[i]) xor (StartKey shr 8));
StartKey:= (Byte(InString[i]) + StartKey)*MultKey + AddKey;
end;
end;

{$R+}
{$Q+}
exports
Encrypt, Decrypt;
end.



Shaman_Naydak   (2002-04-16 10:25) [5]

Странно. sharemem точно помогает.. перекомпили все еще раз..
Ну а на крайняк перепиши, используя WideString (только в нем один символ = 2 байта, учти!)



OlegG   (2002-04-16 10:37) [6]

> Shaman_Naydak ©
Перекомпилировал...
На FreeLibrary(LibHandle); теперь не ругается...
Но зато при закрытии приложения вылетает ошибка:
"Исключение неизвестное программное исключение (0x0eedfade) в приложении по адресу 0x77e8f142" И предлагает подтвердить или отменить...



SP   (2002-04-16 11:35) [7]

Напиши stdcall после объявления функции...



Shaman_Naydak   (2002-04-16 12:30) [8]

и Еще..
поставь shareMem первым файлом в проекте тоже, а не в unit"e

ShareMem should always be the first unit listed in any program or library uses clause where it occurs



Севостьянов Игорь   (2002-04-16 12:57) [9]

Повторюсь, но согласен с

SP © (16.04.02 11:35)
Напиши stdcall после объявления функции...

и в проекте и в DLL



Севостьянов Игорь   (2002-04-16 13:02) [10]

Кстати, ShareMem при использовании PChar не обязателен (зачем таскать за собой BORLANDMM.DLL) просто не забывай что PChar заканчивается на #0 символе, поэтому делай проверку в твоих процедурах на этот символ и придумай ему замену...



REA   (2002-04-16 13:07) [11]

Если передавать строку, то ShareMem.
Если передаешь PChar, который из строки, то буффер объяви статически. Если в процессе он опять преобразуется с String, то используй SetString. Само сабой нулей в строке встречаться не должно (либо передавай еще длину отдельно).



OlegG   (2002-04-16 13:14) [12]

Всем большое спасибо!
Действительно дело в ShareMem - надо было в проекте первым поставить...



OlegG   (2002-04-16 14:32) [13]

Люди, у меня в связи со всем этим возник еще один вопрос:
Все предыдущее стало работать нормально, но если я кладу закриптованную строку, содержащую #0 в таблицу Paradox, то все опять обрезается... Может можно что-нибудь сделать без переделки алгоритма криптования?



MBo   (2002-04-16 14:41) [14]

у тебя зашифр. строка может включать все символы от 0 до 255?
Если нет, MBo © (16.04.02 09:10) 4 строка



Anatoly Podgoretsky   (2002-04-16 14:50) [15]

Да, преобразовывать в ASCII (32..255)



Reindeer Moss Eater   (2002-04-16 14:51) [16]

В парадох в этом случае надо писать не в строковое поле



OlegG   (2002-04-17 07:04) [17]

> Anatoly Podgoretsky
Т.е. вы имеете в виду, что после того как закриптовали строку (содержит #0) ее надо преобразовать в ASCII, а только потом записывать в таблицу? А если потом понадобиться декриптовать, то нужно будет сначала сделать обратное преобразоание?

> Reindeer Moss Eater
А в какое же тогда поле лучше записывать?



OlegG   (2002-04-18 08:38) [18]

Люди, вы про меня не забыли?



Cobalt   (2002-04-19 08:48) [19]

Видимо, имеется в виду BLOB-Поле




Форум: "Основная";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.05.02;
Скачать: [xml.tar.bz2];




Наверх





Память: 0.76 MB
Время: 0.024 c
3-2497            Sam                   2002-04-11 17:23  2002.05.02  
MySQL and Delphi6


1-2528            Демон                 2002-04-21 14:36  2002.05.02  
Проблема с 6-ой ДЕЛФЁЙ


1-2520            Демон                 2002-04-21 12:13  2002.05.02  
Скажите, пж-ста, как поместить HTML-документ на форме не применяя


1-2576            MVova                 2002-04-19 14:21  2002.05.02  
COM + Служба


1-2536            55555                 2002-04-18 11:12  2002.05.02  
форма