Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Проблема с 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-пакетами или отказ от длинных строк.


Наверх

Титульная страница Поиск, карта сайта Написать письмо