Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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.52 MB
Время: 0.008 c
1-60249
Damx%%
2003-06-05 21:42
2003.06.19
Вопрос о StringGrid.


3-60070
Nikolai_S
2003-05-28 12:43
2003.06.19
Как обновить только текущую запись в TADOQuery?


14-60339
Udjin
2003-05-31 00:18
2003.06.19
13 билет на экзамене


1-60129
reticon
2003-06-05 22:59
2003.06.19
просмотр файлов различных типов


1-60133
Xmen
2003-06-06 13:34
2003.06.19
Помогите как можно сделат генератор случайных чисел





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский