![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Проблема с DLL. Уже совсем ничё не понимаю.... [D6, WinXP]
Konsul © (2006-08-01 09:07:00)Здравствуйте, народ!
Проблема у меня с использованием DLL. В одной книге вычитал как вызвать dll на этапе выполнения.Осуществляю это таким образом:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
type TDetFunction=function(): string; stdcall;
procedure TForm1.Button1Click(Sender: TObject);
var
HInst: THandle;
FPointer: TFarProc;
DetLib: TDetFunction;
dllType: string;
begin
HInst:=loadLibrary(PChar('D:\my_progs\Cont_prot\libs\Prot_Gen.dll'));
if HInst>0 then
try
FPointer:=GetProcAddress(HInst,PChar('DetLib'));
if FPointer<>nil then
begin
DetLib:=TDetFunction(FPointer);
dllType:=DetLib;
showmessage(dllType);
end
else showmessage('Функция DLL не найдена!');
finally
FreeLibrary(Hinst);
end
else
showmessage('Библиготека не найдена!');
end;
end.
Т.е. в данном примере мы просто получаем от DLL некое значение для переменной dllType (неважно, что оно значит).
Главное - что имя файла библиотеки можно назначать уже по ходу выполнения программы.
А исходник DLL вот:
library Prot_Gen;
uses
SysUtils,
Classes;
{$R *.res}
function DetLib(): string; stdcall;
begin
result:='Простой текст';
end;
exports
DetLib;
end.
И при запуске проги всё в принципе выолняется как надо, т.е. она выводит сообщение "Простой текст". Но по завершению процедуры TForm1.Button1Click выскакивает ошибка EAccessViolation. Методом комментирования разных строк в процедуре TForm1.Button1Click выяснил, что ошибка не генерируется только если закомментровать строку dllType:=DetLib, т.е. предотвратить само выполение процедуры, ради которой пишется вызов библиотеки и т.п.
Вот в чём проблема? Почему такая ошибка возникает?
Плз, помогите!!!
Konsul (2006-08-01 10:16:00) [1]Всё, получилось! Всем спасибо!
iva (2006-08-01 09:57:00) [2]либо использовать короткие строки
Ketmar (2006-08-01 09:52:00) [3]и, кстати, раз уж всё-равно DLL жёстко "заточена" под Delphi (string) -- можно выкинуть stdcall.
DprYg (2006-08-01 09:21:00) [4]Лучше применять передачу строк через тип PChar
begin...end (2006-08-01 09:17:00) [5]Поскольку функция, находящаяся в DLL, возвращает длинную строку (string), нужно добавить модуль ShareMem первым :
1) в список uses библиотеки;
2) в список uses файла проекта ( DPR , а не PAS) основного приложения.
Об этом написано в комментарии, который Вы видите в окне редактора при создании новой библиотеки.
Есть и другие методы решения: например, компиляция обоих проектов с runtime-пакетами или отказ от длинных строк.