![]() |
|
|
|
|
#1
|
|||
|
|||
|
Здравствуйте уважаемые знатоки, хочу задать вопрос по dll в delphi. Вернее хочу увидеть пример кода, задача сдледующая, в библиотеку передаётся строка, обрабатывается функцией и возращается результат, тоже строка, функция выполняется динамически. Казалось бы что проще, но возникает проблема доступа к памяти, поиск по интернету вернул несколько вариантов решения, во первых почитать внимательно комментарий новосозданой dll, да sharemem использовать пробывал, как советуют, строка передаётся, но при выходе из программы всё равно выскакивает ошибка, при использовании pchar, возращаются неверные данные (не имею опыта использования pchar), использовать widestring (брал по примеру на каком то форуме), даёт ошибку памяти сразу при вызове функции, вообщем ответа по различным запросам в поиске я не нашёл, кто может показать рабочий пример кода по моей задаче?
Последний раз редактировалось xanrias, 11.08.2010 в 03:10. |
|
#2
|
|||
|
|||
|
Код:
// DLL procedure ProcStr(AIn : PChar; AOut : PChar); begin StrCopy(AIn, AOut); end; // Вызов var AIn, AOut : PChar; begin AIn := 'aaa'; GetMem(AOut,StrLen(AIn)+1); ProcStr(AIn,AOut); ... FreeMem(AOut, StrLen(AIn)+1); end; При этом AIn и AOut должны быть инициализированны в вызывающем коде. Если у тебя другая длинна выходной строки, то надо передавать внутрь размер буфера, а на выходе еще получать код возврата в виде размера требуемой памяти (как в WinAPI): Код:
// DLL
function ProcStr(AIn : PChar; Buf : PChar; BufLen : Integer) : Integer;
begin
Resul := 0; // Success
If BufLen >= StrLen(AIn)
Then StrCopy(Ain, AOut)
Else Result := StrLen(AIn);
end;
// Вызов
var
AIn, AOut : PChar;
szLen : Integer;
begin
AIn := 'aaa';
szLen := 0;
Repeate
GetMem(AOut,szLen);
szLen := ProcStr(AIn, AOut, szLen);
Until szLen = 0;
...
FreeMem(AOut,szLen);
end;Если все-таки хочется выделять память в DLL, то надо сделать специальнцю функцию в DLL, которая будет освобождать выделенну. в DLL память. Пример писать не буду, бо как просто - вызов FreeMem переноситься в DLL. |
|
#3
|
|||
|
|||
|
создал библиотеку
Код:
library Project2; uses ShareMem,SysUtils, Classes; procedure ProcStr(AIn : PChar; AOut : PChar); begin StrCopy(AIn, AOut); end; exports ProcStr; begin end. пробую вызывать Код:
unit Unit1;
interface
uses
sharemem,Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
btn1: TButton;
procedure btn1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
ProcStr:procedure (AIn : PChar; AOut : PChar);
LibHandle: THandle;
implementation
{$R *.dfm}
procedure TForm1.btn1Click(Sender: TObject);
var
AIn, AOut : PChar;
begin
@ProcStr := nil;
LibHandle := LoadLibrary('project2.DLL');
{Если все OK}
if LibHandle >= 32 then begin
@ProcStr := GetProcAddress(LibHandle,'ProcStr');
if @ProcStr <> nil then
AIn := 'aaa';
GetMem(AOut,StrLen(AIn)+1);
ProcStr(AIn,AOut);
ShowMessage(AOut);
end;
FreeLibrary(LibHandle);
FreeMem(AOut, StrLen(AIn)+1);
end;
end.получаю ошибку памяти. |
|
#4
|
||||
|
||||
|
Простой примерчик, проверял работает:
Длл: Код:
Library MyDLL;
Uses SysUtils;
Function ProcStr(AIn: PChar): PChar;
Var
T: PChar;
begin
T:= PChar('Надпись: ' + AIn);
Result:= T;
end;
Exports ProcStr;
begin
end.Код:
procedure TForm1.Button1Click(Sender: TObject);
Var
ProcStr: Function(AIn: PChar): PChar;
LibHandle: THandle;
AIn: PChar;
begin
LibHandle:= LoadLibrary('Project1.dll');
@ProcStr:= GetProcAddress(LibHandle, 'ProcStr');
AIn:= PChar(Edit1.Text);
ShowMessage(ProcStr(AIn));
FreeLibrary(LibHandle);
end; |
|
#5
|
|||
|
|||
|
Большое спасибо всем кто помог.
Работает, но при выходе из программы всё так же получаем ошибку памяти, вот на другом форуме с исходниками, если кому потребуется. http://www.cyberforum.ru/delphi-begi...tml#post899869 |