Форум: "Основная";
Текущий архив: 2003.06.19;
Скачать: [xml.tar.bz2];
Вниз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;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.007 c