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

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

Ошибка обращения по адресу при вызове функции из dll


kasper111 ©   (2005-01-22 13:00:00) 

помогиту плызз
вот ..исходники dll
library ean;

{ Important note about DLL memory management: ShareMem must be the
 first unit in your library's USES clause AND your project's (select
 Project-View Source) USES clause if your DLL exports any procedures or
 functions that pass strings as parameters or function results. This
 applies to all strings passed to and from your DLL--even those that
 are nested in records and classes. ShareMem is the interface unit to
 the BORLNDMM.DLL shared memory manager, which must be deployed along
 with your DLL. To avoid using BORLNDMM.DLL, pass string information
 using PChar or ShortString parameters. }

uses
 ShareMem,Windows,
 Messages,
 SysUtils,
 Classes,
 Db,
 ADODB,
 Forms,  
 Unit1 in 'Unit1.pas' {FmEan};

{$R *.RES}
function Init_Dll(ApHandle :THandle) :Integer; {}
begin
Application.Handle := ApHandle;
FmEan := TFmEan.Create(Application);
//fmEan.FConnection.Connection := KisConnect;
Init_Dll:=1;
FmEan.ShowModal;
end;

Exports
Init_Dll;

begin
end.

вот вызывающего модуля
unit Unit1;

interface

uses
 ShareMem,Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 StdCtrls, Db, ADODB;

type
 TForm1 = class(TForm)
   Button1: TButton;
   ADOConnection1: TADOConnection;
   procedure Button1Click(Sender: TObject);

 private
   { Private declarations }
 public
   { Public declarations }
 end;
type
ELoadErrorDLL = class(Exception); {56353 48806 ошибка при загрузке DLL}

{ Процедура экспортится из ShareLib, для работы с Shared memory }
//procedure GetDLLData(var AGlobalData: TPointer_GD); StdCall External 'SHARELIB.DLL';

var
 Form1: TForm1;
 init_Dll: function(ApHandle :THandle):Integer;

implementation

{$R *.DFM}

procedure TForm1.Button1Click(Sender: TObject);
var
libHandle : Thandle;
begin

LibHandle :=LoadLibrary(Pchar(ExtractFilePath(Application.ExeName)+'ean.dll'));
@init_dll:=GetProcAddress(libHandle,'init_dll');
init_Dll(Application.Handle);

end;

end.

при попытке вызвать из dll функцию init_dll вылетает ошибка обращения по адресу памяти... не подскажите что я упустил??


GuAV   (2005-01-22 15:11:00) [1]

Digitman ©   (22.01.05 14:49) [7]

> проще и надежней будет передать параметром не хэндл
> окна, а ссылку на объект Application, созданный
> хост-приложением .. в этом случае будет все в порядке
> и с taskbar'ом и со владением создаваемых в библ-ке
> VCL-объектов, имеющих owner'ом любой из VCL-объектов в
> составе хост-приложения


Проблемы с владением не вижу. Какая связь между переменнной application и owner'ом ? Формы приложения могут быть owner'ом не зависимо от того, является ли их owner'ом application или нет. Как мне представляется, всё что необходимо для такого владения - это sharemem, чтобы объекты созданные в dll могли освобождаться в ехе.
Также не вижу смысла владения dll - компонентов ехе компонентами. IMHO, они должны владется именно dllовским application, чтобы быть благополучно освобождёнными при выгрузке dll.

В данной задаче, вообще-то смысла владения нет - переменную модальной формы можно сделать локальной, и освобождать эту форму сразу после попытки использования.


kasper111   (2005-01-22 14:51:00) [2]

спасибо всем большое... все получилось()


Digitman   (2005-01-22 14:49:00) [3]


> GuAV ©   (22.01.05 14:40) [6]


> IMHO Вы зря придрались к этому


просто я вижу неосознаннаное или не вполне осознанное автором следование комментариям из справки


> Даже в этом случае лучше присвоить Application.Handle


коль оба взаимодействующих проекта используют VCL, проще и надежней будет передать параметром не хэндл окна, а ссылку на объект Application, созданный хост-приложением .. в этом случае будет все в порядке и с taskbar'ом и со владением создаваемых в библ-ке VCL-объектов, имеющих owner'ом любой из VCL-объектов в составе хост-приложения


GuAV   (2005-01-22 14:40:00) [4]


> не иначе как модально ..

Даже в этом случае лучше присвоить Application.Handle т.к. иначе будет две кнопки на taskbar и возможность активировать главную формы с помощью них... IMHO Вы зря придрались к этому.


Digitman   (2005-01-22 14:26:00) [5]


> GuAV ©   (22.01.05 14:14) [4]


ну и что ? это вовсе не обязательное требование... тем более с учетом того, что автор , как видно из кода, визуализирует свою форму не иначе как модально ..


GuAV   (2005-01-22 14:14:00) [6]


> ЗАЧЕМ ты передаешь параметром в библ.ф-цию хэндл
> гл.окна приложения ? каков глубоко скрытый смысл в
> этом ?

Handle + F1 -> Handle property (TApplication) ->Note.


Digitman   (2005-01-22 13:30:00) [7]

ShareMem must be the first unit in your library's USES clause AND your project's (select Project-View Source) USES clause

для начала, если уж необходимо, выполни эти требования именно так как указазано в замечании, безо всякой отсебячины

но необходимости такой в коде твоем нет, потому что нет условий, опять же указанных в том самом замечании :

if your DLL exports any procedures or functions that pass strings as parameters or function results

это - раз.

теперь дальше поехали ..

ЗАЧЕМ ты передаешь параметром в библ.ф-цию хэндл гл.окна приложения ? каков глубоко скрытый смысл в этом ?

ну и наконец о главном - ошибка происходит из-за того что GetProcAddress вернула nil : импортируемая ф-ция имеет имя "Init_Dll", в то время как ты желаешь получить адрес ф-ции с именем "init_dll", которой попросту нет в библиотеке .. имена эксп.ф-ций регистрозависимы !


GuAV   (2005-01-22 13:08:00) [8]

И вообще, кто будет проверять результат
LibHandle :=LoadLibrary(Pchar(ExtractFilePath(Application.ExeName)+'ean.dll'));
if LibHandle = 0 then RaiseLastWin32Error;
@init_dll:=GetProcAddress(libHandle,'init_dll');
if not Assigned(init_dll) then RaiseLastWin32Error;

И хендл dll надо FreeLibrary. И смысл дин загрузки ?


GuAV   (2005-01-22 13:05:00) [9]


> ' init_ dll'



>Exports
> Init_ Dll;


Есть подозрение что в регистре дело


Наверх

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