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

Вниз

DLL II   Найти похожие ветки 

 
TButton ©   (2003-06-04 15:01) [0]

И все-таки, как объявить в проге класс из DLLки?


 
y-soft ©   (2003-06-04 15:57) [1]

Что понимается под subj? Класс-оболочка, методы которого являются обертками для экспортируемых Dll функций или же Dll экспортирует сразу класс? Во втором случае: имеется в виду класс в терминах Object Pascal или, например, CPP?


 
TButton ©   (2003-06-04 18:45) [2]

имеется ввиду

library myLib;

uses
ShareMem,
SysUtils,
Classes;

type
myType = record
dam,def:integer;
kind:byte;
count:byte;
end;

TInv = object
items:array[1..12] of myType;
procedure Init;
procedure Put(i:myType);
function Get:myType;
end;

{$R *.RES}

{ TInv }

function TInv.Get: myType;
begin

end;

procedure TInv.Init;
begin

end;

procedure TInv.Put(i: myType);
begin

end;

begin
end.


вот. а теперь я хочу создать в проге переменную типа TInv.


 
Palladin ©   (2003-06-04 18:48) [3]

много хочешь


 
Юрий Зотов ©   (2003-06-04 18:49) [4]

Вынесите все это в отдельный юнит и юзайте его и в программе, и в DLL. Только имейте в виду, что TInv в DLL и TInv в программе - это будут разные классы.


 
Palladin ©   (2003-06-04 18:53) [5]

ситуация с классом не описанным в программе, но описанном в dll в принципе разрешима, при помощи pointer и type casting, вот только работать с этим классом возможно будет только из dll, создавать и уничтожать там же... а в основной программе возможно лишь хранение объекта...

проще тогда уж создавать com-объекты и работать с ними...


 
Serginio   (2003-06-04 18:53) [6]

Используй интерфейсы.


 
TButton ©   (2003-06-04 18:58) [7]

просто хотелось скинуть классы в DLLку и потому, случись что не перестраивать всю прогу, а тока DLLу перепислять. т.е. я так понял, затея моя глупая и придется классы расписывать в юните, да и когда я буду менять чо-та перекомпилирывать всю прогу и заменять клиентам екзешник...


 
VMcL ©   (2003-06-04 19:01) [8]

>TButton © (04.06.03 18:58)

IUnknown, IDispatch, etc. (см. Serginio (04.06.03 18:53))


 
Skier ©   (2003-06-04 19:03) [9]


> и заменять клиентам екзешник...

А у тебя клиенты есть ? :)


 
TButton ©   (2003-06-04 19:03) [10]

если честно я по части интерфейсов - пень


 
Юрий Зотов ©   (2003-06-04 19:06) [11]

> TButton © (04.06.03 18:58)
> просто хотелось скинуть классы в DLLку

Так скиньте их в BPL и все проблемы исчезнут.


 
Serginio   (2003-06-04 19:09) [12]

File\New\Other\ActiveX\Com Object


 
TButton ©   (2003-06-04 19:23) [13]

не ну я посмотрел... а вообще для каких целей используются такие объекты? а то ощущение такое будто пытаюсь поставить на Запор двигатель от боинга...


 
panov ©   (2003-06-04 20:03) [14]

http://home.ural.ru/~panov
там есть пример


 
y-soft ©   (2003-06-05 10:38) [15]

>Palladin © (04.06.03 18:53)
ситуация с классом не описанным в программе, но описанном в dll в принципе разрешима, при помощи pointer и type casting, вот только работать с этим классом возможно будет только из dll, создавать и уничтожать там же... а в основной программе возможно лишь хранение объекта...

>Юрий Зотов © (04.06.03 19:06)
Так скиньте их в BPL и все проблемы исчезнут.

Доступ к классу, созданному в Dll, через кастинг не лучший способ, т.к. требует, чтобы Dll и приложение были скомпилированы в одной версии Delphi, т.е. сложнее становится модифицировать код. По этой же причине неуниверсальны и BPL.

COM вещь хорошая, но для многих случаев неоправданно сложная.

Но существует еще один старый способ - экспортировать методы класса через функции-обертки. Примерно так (только сам принцип, реально необходимо еще предусмотреть обработку ошибок):

В Dll:


Program SomeDll;
uses
SomeClass;
begin
end.

Unit SomeClass;
interface
uses Classes;

type
TSomeClass = Class
private
fSomeValue : integer;
procedure SetSomeValue(const Value : integer);
public
Constructor Create;
property SomeValue : integer
read fSomeValue write SetSomeValue;
end;

//Функции-обертки

function CreateSomeClass : pointer; export;
function FreeSomeClass(Ref : pointer); export;
function SomeClassGetSomeValue(Ref : pointer) : integer; export;
function SomeClassSetSomeValue(Ref : pointer; const Value : integer); export;
implementation
constructor TSomeClass.Create;
begin
inherited;
fSomeValue := 0;
end;

procedure TSomeClass.SetSomeValue(const Value : integer);
begin
if fSomeValue <> Value then
fSomeValue := Value;
end;
end.

function CreateSomeClass : pointer; export;
begin
Result := TSomeClass.Create;
end;

function FreeSomeClass(Ref : pointer); export;
begin
TSomeClass(Ref).Free;
end;

function SomeClassGetSomeValue(Ref : pointer) : integer; export;
begin
Result := TSomeClass(Ref).SomeValue;
end;
function SomeClassSetSomeValue(Ref : pointer; const Value : integer); export;
begin
TSomeClass(Ref).SomeValue := Value;
end;

exports
CreateSomeClass,
FreeSomeClass,
SomeClassGetSomeValue,
SomeClassSetSomeValue;
end.


В приложении (пропущена загрузка/выгрузка Dll и обработка ошибок):

...
interface
...
type
TSomeClassWrapper = class
private
fRef : pointer;
function GetSomeValue : integer;
procedure SetSomeValue(const Value : integer);
public
Constructor Create;
Destructor Destroy; override;
end;

TCreateSomeClass = function : pointer;
TFreeSomeClass = procedure(Ref : pointer);
TSomeClassGetSomeValue = function(Ref : pointer) : integer;
TSomeClassSetSomeValue = procedure(Ref : pointer; const

var //При иницализации получить адреса через GetProcAddress
CreateSomeClass : TCreateSomeClass;
FreeSomeClass : TFreeSomeClass;
SomeClassGetSomeValue : TSomeClassGetSomeValue;
SomeClassSetSomeValue : SomeClassSetSomeValue;
implementation

Constructor TSomeClassWrapper.Create;
begin
inherited;
fRef := CreateSomeClass;
end;

Destructor TSomeClassWrapper.Destroy;
begin
FreeSomeClass;
inherited;
end;

function TSomeClassWrapper.GetSomeValue : integer;
begin
Result := SomeClassGetSomeValue(fRef);
end;

procedure SetSomeValue(const Value : integer);
begin
SomeClassSetSomeValue(fRef, Value);
end;
...


 
y-soft ©   (2003-06-05 10:40) [16]

Опечатка:

Destructor TSomeClassWrapper.Destroy;
begin
FreeSomeClass(fRef);
inherited;
end;




 
Maks Realov   (2003-06-05 12:38) [17]

Вопрос по теме:

А что, разве нельзя создать объект в DLL-ке и передать ссылку на него в главную программу; главная программа использует объект, "возвращает управление" в DLL и уже DLL-ка разрушает объект и освобождает ресурсы?
Менеджеры памяти у DLL и главного приложения разные - это понятно, но АП то одно.


 
Skier ©   (2003-06-05 12:40) [18]

>Maks Realov (05.06.03 12:38)
И разные указатели на VMT и таблицу RTTI...


 
y-soft ©   (2003-06-05 13:12) [19]

>Maks Realov (05.06.03 12:38)

А что, разве нельзя создать объект в DLL-ке и передать ссылку на него в главную программу; главная программа использует объект, "возвращает управление" в DLL и уже DLL-ка разрушает объект и освобождает ресурсы?

Можно, и так даже делают, но чревато, не спасает даже использование одних и тех же модулей с определением классов, т.к. в разных версиях Delphi могут быть разными базовые классы

Вот буквально недавно пришлось разбирать случай:

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


 
Skier ©   (2003-06-05 13:18) [20]


> При вызове экспортируемой функции, возвращающей TMemoryStream
> возникло AV. Выяснилось, что приложение писалось в D5, а
> библиотека в D7...

Сильно сомневаюсь что дело в разных версиях...


 
Aleksey Pavlov ©   (2003-06-05 13:18) [21]

COM - просто и надёжно. А главное без всяких несуразностей с версиями, типом компилятора и т.д.


 
reonid ©   (2003-06-05 13:28) [22]

Aleksey Pavlov © (05.06.03 13:18)

Не пугай людей страшными словами.
Здесь можно вполне обойтись и интерфейсами.
Интерфейс - это ещё не СОМ, в нём-то ничего сложного нет.


 
АлексейК   (2003-06-05 14:05) [23]

Если методы класса пометить как виртуальные, то их можно будет вызвать из DLL.


 
Suntechnic ©   (2003-06-05 19:28) [24]

АлексейК (05.06.03 14:05)
Если методы класса пометить как виртуальные, то их можно будет вызвать из DLL.


Это что-то новенькое из жизни виртуальных методов :)


 
Serginio   (2003-06-05 19:51) [25]

С интерфейсом можно работать и без фабрики классов (COM).А Основным премуществом является GUID и у интерфейсов все виртуальные методы. Кроме всего прочего объект может содержать несколько интерфейсов и моя любимаю директива Implements, чтобы не создавать каждый раз новые объекты. Сборка мусора.


 
Skier ©   (2003-06-05 19:52) [26]


> А Основным премуществом является GUID и у интерфейсов все
> виртуальные методы.

Правда ?



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

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

Наверх




Память: 0.53 MB
Время: 0.017 c
9-60006
K@zzel
2003-01-10 14:48
2003.06.19
как отчистить DXDraw


1-60187
aleman
2003-06-05 10:05
2003.06.19
Как закрасить сектор круга?


6-60300
xman
2003-04-18 12:03
2003.06.19
Сеть + Аудио


7-60431
ers
2003-04-14 13:48
2003.06.19
Количество файлов!


11-60099
Alexander
2002-09-25 16:06
2003.06.19
Эквивалентны ли функции StrIComp из StrUtils и StrComp из KOL?