![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как "динамический" вызать конструктор? [D7, WinXP]
zamtmn © (2006-07-31 14:34:00)Никак не получается "динамически" вызвать конструктор для object`a. Делаю чтото вроде вотэтого:
program Project1;
{$APPTYPE CONSOLE}
uses
SysUtils;
type
testobj=object
constructor init;
end;
SimpleProcOfObj=procedure of object;
var obj:testobj;
tm:tmethod;
constructor testobj.init;
begin
writeln('init;')
end;
begin
tm.Code:=@testobj.init;
tm.Data:=@obj;
SimpleProcOfObj(tm);
writeln('end.');
readln;
end.
На FPC всё компилится и работает, на DELPHI7 никак. если constructor заменить на procedure то все работает, но нужно именно конструктор - чтоб VMT проинициализировалась:(
GrayFace (2006-08-04 09:18:00) [1]изменение TBM
В смысле изменение указателя на TBM в объекте.
GrayFace (2006-08-04 09:17:00) [2]Ну дак что ты решил? Есть, как минимум 2 нормальных решения проблемы - [79] или такое: ZeroMem, конструктор базового боъекта, изменение TBM.
Игорь Шевченко (2006-08-02 11:26:00) [3]
> ладно здаюсь, не привязка, ПОДДЕРЖКА
> Мне поддержка COM любым объектом моей программы ненужна
Ты бредишь. Читай [49] до полного просветления.
zamtmn (2006-08-01 18:51:00) [4]у меня на 10.0.2151.25345
program Project1;
type
TestObj = object
private
procedure Test;
end;
procedure TestObj.Test;
begin
readln;
end;
begin
end.
компилируешся. патчей не ставил
>>QueryInterface = 12 - то моя прога привязана к ком?
>>Это для поддержки ком, а конкретно IUnknown.QueryInterface. Но и без ком, всё будет отлично работать.
ладно здаюсь, не привязка, ПОДДЕРЖКА
Мне поддержка COM любым объектом моей программы ненужна
jack128 (2006-08-01 18:30:00) [5]zamtmn (01.08.06 0:12) [34]
пост 27 прекрасно компилируется на D2006 без всяких патчей.
ну значит у меня дома какой то особенный дельфи стоит, на котором эта фишка не компилируется. (Borland® Delphi® for Microsoft® Windows™ Version 10.0.2151.25345 )
zamtmn © (01.08.06 12:38) [38]
vmtQueryInterface = 0;
vmtAddRef = 4;
vmtRelease = 8;
vmtCreateObject = 12;
ниче не напоминает?
а.. То есть если я в своей программе объявлю константу const QueryInterface = 12 - то моя прога привязана к ком?
tesseract © (01.08.06 13:29) [43]
находиться "следы" в частности ссылки на GUID у Tobject. Хотя ИМХО это RTTI- радости.
Это для поддержки ком, а конкретно IUnknown.QueryInterface. Но и без ком, всё будет отлично работать.
И вообще, дельфи совместима с ком, но не привязана к нему. Например интерфейсов без guid'а в ком быть не может, а в дельфи есть.
zamtmn (2006-08-01 18:09:00) [6]допустим перегрузили + и *
d:=(a+b)*c
можно посчитать только с применением промежуточной пременной или заменив значение a(b)
без автодеструктора компилятор забудет о промежуточной переменной:(
и если это сложные типы
например
record
pdata:^data;
x,y....:intrger;
end;
будет утечка памяти
кстати в freepascal вот шаблоны появились:), раз уж пошла тема про "сианизацию" паскаля
Джо (2006-08-01 17:57:00) [7]> а фишка с перегрузкой операторов без автоматических деструкторов
> малоприменима
Почему?
zamtmn (2006-08-01 17:55:00) [8]
> В том и фишка, что в D2006 в них методы можно объявлять
> и даже перегрузку операторов. Ну, и конструкторы (с параметрами).
>
Это всё есть у обжекта, а фишка с перегрузкой операторов без автоматических деструкторов малоприменима
Джо (2006-08-01 17:51:00) [9]> дак они у меня работают, только соответственно методов не
> имеют
В том и фишка, что в D2006 в них методы можно объявлять и даже перегрузку операторов. Ну, и конструкторы (с параметрами).
zamtmn (2006-08-01 17:47:00) [10]>>Мои предложения не отличатся оригинальностью - не маяться дурью и использовать class
и в чем будет принципиальная разница? ну разве что ненадо хранить предка и поля
>>Или использовать records в Delphi 2006 :)
дак они у меня работают, только соответственно методов не имеют
Джо (2006-08-01 16:52:00) [11]Или использовать records в Delphi 2006 :)
Сергей М. (2006-08-01 16:31:00) [12]
> zamtmn © (01.08.06 16:26) [78]
> ваши предложения?
Мои предложения не отличатся оригинальностью - не маяться дурью и использовать class.
GrayFace (2006-08-01 16:29:00) [13]zamtmn © (01.08.06 16:25) [77]
ZeroMem не отделаться, если объект создает дополнительные структуры, нужно вызывать родные конструктор/деструктор
А понизить его ранг до процедуры и после ZeroMem вызывать по-обычному?
zamtmn (2006-08-01 16:26:00) [14]>>Ловля блох.
ваши предложения?
zamtmn (2006-08-01 16:25:00) [15]>>Проще вызвать ZeroMem и записать адрес TBM в нужное место (наверняка
>>это начало). Ты все-равно зависишь от структуры TBM и места где лежит на
>>него указатель, так хоть не будешь зависить от реализации конструкторов.
ZeroMem не отделаться, если объект создает дополнительные структуры, нужно вызывать родные конструктор/деструктор
Сергей М. (2006-08-01 16:22:00) [16]
> GrayFace © (01.08.06 16:
Ловля блох.
GrayFace (2006-08-01 16:14:00) [17]tesseract © (01.08.06 13:29) [43]
> Уже в D7 не работают property.
какие property?
В OLE/классах всё работает.
В object'ах тоже можно объявлять свойства, но они не работают.
begin...end © (01.08.06 13:27) [42]
Посмотрел - действительно. Вот уж не думал, что у object'ов могут быть виртуальные методы. Только _ObjSetup не инициализирует TBM, а инициализирует сам объект - заполняет нулями и пишет в нужное место указатель на TBM.
zamtmn © (01.08.06 13:39) [46]
вобщето формально constructor и procedure одно и тоже, только конструктор еще вызывает ObjSetup для инициализации VMT
Формально constructor и procedure - разные слова. На практике - тоже.
zamtmn © (01.08.06 14:36) [62]
Проще вызвать ZeroMem и записать адрес TBM в нужное место (наверняка это начало). Ты все-равно зависишь от структуры TBM и места где лежит на него указатель, так хоть не будешь зависить от реализации конструкторов.
Сергей М. © (01.08.06 14:43) [64]
Если же ты заботишься о результирующем объеме кода - это тебе не сюда: везде будет присутствовать и VMT, и RTTI, и прочие таблицы .. практически в полном объеме ..
В object есть только VMT. Ни RTTI, ни Interface Table, ни Dinamic Table, ни имени класса, ни предка. А значит, не нужно о них заботиться при создании VMT. В общем, неплохое решение.
Сергей М. (2006-08-01 15:48:00) [18]мда..
zamtmn (2006-08-01 15:39:00) [19]
PFieldDescriptor=^FieldDescriptor;
FieldDescriptor=record
FieldName:string;
FieldType:gdbtypedesk;
Offset,Size:integer;
Attributes:word;
end;
PMetodDescriptor=^MetodDescriptor;
MetodDescriptor=record
MetodName:string;
MetodAddr:pointer;
Attributes:word;
end;
PRecordDescriptor=^RecordDescriptor;
RecordDescriptor=object(UserTypeDescriptor)
Fields:GDBOpenArrayOfData;
SimpleMenods:GDBOpenArrayOfData;
Parent:PRecordDescriptor;
PVMT:pointer;
constructor init;
procedure AddField(var fd:FieldDescriptor);
procedure AddMetod(mn:string;ma:pointer;attr:word);
procedure RegisterVMT(pv:pointer);
procedure RunMetod(mn:string;obj:pointer);
procedure AddConstField(var fd:FieldDescriptor);
procedure CopyTo(RD:PRecordDescriptor);
end;
описанье всего остального
zamtmn (2006-08-01 15:32:00) [20]забыл
type
SimpleProcOfObj=procedure of object;
тробегает по дереву зарегистрированных объектов и вызывает метод, конструктор, функцию у ближайшего родителя с именем mn, вот ещебы передачу параметров прикрутить....