Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2002.07.25;
Скачать: CL | DM;

Вниз

Вызов из DLL функции exe-шника?   Найти похожие ветки 

 
Brand   (2002-07-14 22:40) [0]

Описываю в exe-шнике функцию, как public
и в DLL-ке пытаюсь вызвать:
Main.Form1.SomeFunction();
А компилятор мне глюк выдает.
???


 
drpass ©   (2002-07-14 23:15) [1]

Он тебе не глюк выдает, а об ошибке сообщает. То, что функция объявлена как public - это еще не повод вызывать ее из DLL. Тем более, что директива public вообще к этому никакого отношения не имеет


 
Brand   (2002-07-14 23:27) [2]

А как?


 
Mystic ©   (2002-07-15 00:10) [3]


> Вызов из DLL функции exe-шника?


1.
Указываешь в DPR файле директиву exports, указываешь после него имя функции, загружаешь EXE путем вызова LoadLibrary и вызываешь функцию. Увы, в твоем случае это не поможет, так как функция Main.Form1.SomeFunction(); принимает еще неявный параметр --- собственно Form1.


----------------------------------------------------------------

2.
Код DLL
=======

type
TMyMethod = procedure of object;

procedure Foo(Method: TMyMethod);
begin
Method();
end;

exports
Foo;


Код проекта
===========

type
TMyMethod = procedure of object;

procedure Foo(Method: TMyMethod); external "Project2.dll" name "Foo";

procedure TForm1.XXX;
begin
ShowMessage("Test");
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Foo(XXX);
end;


Возможные проблемы:

А --- желательно указывать опцию Build with runtime pakages, так иначе возможна ситуация, когда у тебя окажеться подключенным два одинаковых модуля (например Graphics) и при тесном взаимодействии DLL и EXE вылазить нечто вроде Can"t assign TFont to TFont.

B --- пункт A для твоих модулей, которые использует как DLL, так и основной проект. Такие куски лучше оформлять в виде пакетов, что не всегда удобно (как, например, в случае главной формы).

C --- Не забыть про ShareMem



----------------------------------------------------------------

3.
Лично для себя я выработал следующие принципы взаимодействия EXE <-> DLL

A. Создается разделяеый всеми модуль вроде Common.pas, который содержит описание констант, типов и ИНТЕРФЕЙСОВ, используемых в программном продукте. И ЕДИНСТВЕННУЮ переменную для связи EXE <-> DLL. Модуль выглядит примерно так:

interface

uses
Classes,
Controls,
Forms;

const
ERROR_INVALID_PARAM = 1;
ERROR_OBJECT_ALREADY_EXIST = 2;

type
TScriptAttribute = (saSetup, saStandart, saHistory);
TScriptAttributes = set of TScriptAttribute;

IScript = interface(IDriverEvent)
["{4273C7D6-755F-11D6-8E37-00D0C9055876}"]
function GetAttributes: TScriptAttributes;
function GetState: TScriptStates;
function GetActive: Boolean;
end;

..................

IMyIDE = interface
["{4273C7DB-755F-11D6-8E37-00D0C9055876}"]
function ScriptManager: IScriptManager;
procedure RegisterLibrary(const LibPath: string);
function Application: TApplication;
end;

var
MyIDE: IMyIDE;

function GetMyIDE: IUnknown; external "MyIDE.dll" name "GetMyIDE";
procedure SetMyIDE(const NewMyIDE: IUnknown); external "MyIDE.dll" name "SetMyIDE";

implementation

initialization
MyIDE := GetMyIDE as IMyIDE;

// Это для диалоговых окошек
if ModuleIsLib then
if Assigned(MyIDE) then
if Assigned(MyIDE.Application) then
Application.Handle := MyIDE.Application.Handle;
end.

B. Эта единственная переменная инициализируется отдельной DLL примерно так:

var
_MyIDE: IUnknown;

procedure SetMyIDE(const NewMyIDE: IUnknown);
begin
_MyIDE := NewMyIDE;
end;

function GetMyIDE: IUnknown;
begin
Result := _MyIDE;
end;

exports
SetMyIDE name "SetMyIDE",
GetMyIDE name "GetMyIDE";

Основное приложение до загрузки DLL путем LoadLibrary должно вызвать SetMyIDE. Следует обратить внимание на то, что в качестве параметра передается IUnknown. Четверной эффект: во--первых, мы этим избавляется от необходимости включать Forms и другие модули в эту DLL. Кроме того, некорректно выполнять обращения к Application до вызова Application.Initialize --- четыре. Кстати, это приводит к (интересным) глюкам.

C. Это вроде живет, и делает приложение, которое состоит из plug-in-ов и упрощает разработку программ несколькими лицами.



Страницы: 1 вся ветка

Текущий архив: 2002.07.25;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.016 c
1-81210
shelest
2002-07-11 17:00
2002.07.25
Форма в виде подсказки в Win XP.


7-81490
Glonia Zbanov
2002-05-07 13:00
2002.07.25
принтеры


1-81342
Src_Crab
2002-07-12 20:52
2002.07.25
Преобразование String в Integer.


8-81382
McSimm
2001-12-27 15:19
2002.07.25
3DS MAX как OLE-сервер


1-81316
Andy BitOff
2002-07-12 15:43
2002.07.25
Чтение файла