主页
Top.Mail.Ru Yandeks.Metrika
论坛:“主要”;
当前存档:2002.07.29;
下载:[xml.tar.bz2];

向下

使用DLL。 Assign方法不希望被执行.. :( 找到类似的分支


Гас   (2002-07-16 10:01) [0]

Вот в первый раз решил поработать с DLL, все классно получалось, пока не попробовал сделать FFont.Assign(DLLReturnsFont).
Не хочет выполняться!
Пишет "Cannot assign TFont to a TFont".
В чем дело, кто-нибудь знает? Спасибо.



Digitman   (2002-07-16 10:33) [1]


procedure TPersistent.Assign(Source: TPersistent);
开始
if Source <> nil then Source.AssignTo(Self) else AssignError(nil);
结束;

procedure TPersistent.AssignError(Source: TPersistent);
VAR
SourceName: string;
开始
如果Source <>那么
SourceName := Source.ClassName else
SourceName := "nil";
raise EConvertError.CreateResFmt(@SAssignError, [SourceName, ClassName]);
结束;

Отсюда очевидно, что DLLReturnsFont у тебя по какой-то причине равен nil



reonid   (2002-07-16 10:40) [2]

Assign обычно работает через RTTI -
проверяет Source с помощью is/as.
А класс TFont в основном приложении и в DLL - разные классы,
(хотя и идентичные).

Поэтому обычно классы из DLL не экспортируют.



Eugene Lachinov   (2002-07-16 10:42) [3]

Тут наверно, надо разбираться с реализацией Source is TFont :-), и вообще is



Игорь Шевченко   (2002-07-16 10:57) [4]

Font в DLL и Font в EXE имеют разные адреса RTTI, поэтому оператор Is не сработает.



Гас   (2002-07-16 11:58) [5]

Спасибо за внимание, я тут покопал немножко и уже понял, что не так все просто. Но пока не знаю как все-таки передать свойства фонта из DLL. Да и вообще, как передавать объекты?..



Skier   (2002-07-16 12:04) [6]

>Гас

> Но пока не знаю как все-таки передать свойства фонта из
> DLL

Тебе обязательно нужен именно такой подход ?



Digitman   (2002-07-16 12:04) [7]

Передача любого объекта по сути сводится к передаче его свойств. Отсюда и пляши : читаешь значение свойства объекта-источника - записываешь это значение в соотв.свойство объекта-приемника.



Гас   (2002-07-16 12:11) [8]

ToSkier: Мне нужно получить оттуда свойства фонта, не знаю только каким способом это сделать..

ToDigitman: Не хочется верить, что это единственный выход. :) Получается очень неуниверсально что-ли.. хех.



Digitman   (2002-07-16 12:17) [9]

а ты что думаешь - метод Assign() делает это каким-то чудесно-волшебным способом ? Точно так же и делает, только во многих случаях - прозрачно для программера да еще и с использованием вспомогательного метода AssignTo()



Skier   (2002-07-16 12:20) [10]

>Гас
Можно так (если не учитывать что св-ва TFont можно записать
в поток) : "собери" свойства TFont в строку, а при получении из DLL разбирай её.



Гас   (2002-07-16 12:48) [11]

Да, Assign я смотрел в исходниках уже, но просто хотел поставить задачу более глобально, то есть как получить доступ к объекту, создаваемому в DLL.. Надо ж ведь научиться делать такое..
А как передать строку из DLL? По-моему это тоже непросто..



Skier   (2002-07-16 12:51) [12]

>Гас

> А как передать строку из DLL?

Нужно передавать не строку, а PChar

> По-моему это тоже непросто..


Проще паренной репы...



Гас   (2002-07-16 12:55) [13]

И кстати, как тогда получить доступ к (Фонт из DLL).Color, (Фонт из DLL).Style и т.п... Должен ведь быть выход.. В хелпе это описано слишком скудно. :(



Гас   (2002-07-16 13:00) [14]

ToSkier : Да, действительно, я не подумал о PChar. Но неужели нет другого решения?..



Digitman   (2002-07-16 13:08) [15]

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

Уточни, где и как декларирована переменная DLLReturnsFont, в каком контексте и каким образом она заполняется ссылкой на некий объект класса TFont



Skier   (2002-07-16 13:08) [16]

>Гас
Можно писать св-ва TFont в TStream через TWriter (?)
但为什么你需要这一切呢?
В чём твоя цель ??



Гас   (2002-07-16 13:40) [17]

> В чём твоя цель ??
Научиться :)



Eugene Lachinov   (2002-07-16 13:46) [18]

function IgnoreProp(const PropName : string) : Boolean;
开始
Result := (CompareText(PropName, "Active") = 0) or
(CompareText(PropName, "Connected") = 0) or
(CompareText(PropName, "Name") = 0)
结束;

procedure CopyObject(const Source, Dest : TObject);
VAR
PropList:PPropList;
i, iPropCount : Integer;
开始
iPropCount := GetPropList(Source, PropList);
for i := 0 to iPropCount - 1 do
with PropList^[i]^ do if not IgnoreProp(Name) then
case PropType^^.Kind of
tkInteger, tkChar, tkWChar, tkEnumeration, tkSet,
tkFloat, tkString, tkLString, tkWString, tkVariant,
tkInt64, tkDynArray : SetPropValue(Dest, Name, GetPropValue(Source, Name));
tkClass : SetObjectProp(Dest, Name, GetObjectProp(Source, Name));
结束
结束;

...

CopyObject(DLLReturnsFont, FFont);



Eugene Lachinov   (2002-07-16 14:10) [19]

Упущен FreeMem

procedure CopyObject(const Source, Dest : TObject);
VAR
PropList:PPropList;
i, iPropCount : Integer;
开始
iPropCount := GetPropList(Source, PropList);
if iPropCount > 0 then try
for i := 0 to iPropCount - 1 do
with PropList^[i]^ do if not IgnoreProp(Name) then
case PropType^^.Kind of
tkInteger, tkChar, tkWChar, tkEnumeration, tkSet,
tkFloat, tkString, tkLString, tkWString, tkVariant,
tkInt64, tkDynArray : SetPropValue(Dest, Name, GetPropValue(Source, Name));
tkClass : SetObjectProp(Dest, Name, GetObjectProp(Source, Name));
结束
最后
FreeMem(PropList)
结束
结束;



Гас   (2002-07-16 14:21) [20]

Похоже, то что нужно, спасибо! Значит, сам объект никак нельзя получить?..



Digitman   (2002-07-16 15:06) [21]

Что есть "получить объект" ?



Гас   (2002-07-16 15:25) [22]

Что-то я слегка запутался уже.. :) Просто хотел сказать, что передавать объект как параметр нельзя, получается.



Mystic   (2002-07-16 15:37) [23]

Проблему может решить установка опции Build with runtime packges (или хотя бы только vcl)

Может еще помогут пара моих соображений по этому вопросу:
http://delphi.mastak.ru/cgi-bin/forum.pl?look=1&id=1026672057&n=0



Гас   (2002-07-16 15:41) [24]

Сапсибо, буду переваривать полученную информацию :)



Digitman   (2002-07-16 17:44) [25]

Почему нельзя ? Можно передавать. Только не сам объект, а адрес существующего экземпляра класса. Адресное пространство-то у хост-процесса и у DLL - одно и то же, RTTI (пусть даже в нескольких экз-рах при отказе от Build with runtime packges) - одна и та же (если хост-приложение и DLL собраны в одной и той же версии Делфи)



Юрий Зотов   (2002-07-16 18:42) [26]

Адрес передать не проблема, проблема в другом.

Хост-программа и DLL компилируются, как два независимых проекта. Поэтому таблица классов в них у каждого своя. TFont в контексте хоста и тот же TFont в контексте DLL - это два входа в РАЗНЫЕ таблицы - то есть, формально - два РАЗНЫХ класса. Поэтому и не срабатывает Assign - в нем не проходит проверка if Source is TFont. То же самое и со всеми остальными классами.

Этих проблем не возникает, если компилировать с run-time пакетами. В противном случае придется делать интерфейсные классы-посредники между DLL и хостом. Приходилось мне лепить такие классы и по собственному опыту могу сказать - лучше используйте run-time пакеты. Просто, надежно и без усилий - в Borland"е совсем не дураки сидят.



Страницы: 1 整个分支

论坛:“主要”;
当前存档:2002.07.29;
下载:[xml.tar.bz2];

楼上









内存:0.64 MB
时间:0.041 c
14-95488
corvinalive
2002-06-30 11:32
2002.07.29
向导创建


1-95396
antoniz
2002-07-16 10:13
2002.07.29
如何在TRichEdit中找到字符的坐标(以像素为单位)


14-95517
Gayrus
2002-06-30 07:17
2002.07.29
Delphi组件


3-95219

2002-07-08 10:53
2002.07.29
定位


3-95260
ALex_Aby
2002-07-07 14:10
2002.07.29
我寻找没有BDE ADO的数据访问





南非荷兰语 阿尔巴尼亚人 阿拉伯语 亚美尼亚 阿塞拜疆 巴斯克 白俄罗斯 保加利亚语 加泰罗尼亚 简体中文 中国(繁体) 克罗地亚 捷克 丹麦语 荷兰人 英语 爱沙尼亚语 菲律宾人 芬兰 法文
加利亚西语 格鲁吉亚语 德语 希腊语 海地克里奥尔语 希伯来语 印地语 匈牙利 北日耳曼语 印度尼西亚人 爱尔兰语 意大利语 日本性玩偶 韩语 拉脱维亚 立陶宛 马其顿 马来语 马耳他语 挪威语
波斯语 波兰语 葡萄牙语 罗马尼亚 俄语 塞尔维亚 斯洛伐克 斯洛文尼亚 西班牙语 斯瓦希里 瑞典语 泰国人 土耳其 乌克兰 乌尔都语 越南人 威尔士语 意第绪语 孟加拉 波斯尼亚
宿务 世界语 古吉拉特语 豪萨语 苗族 伊博 爪哇 卡纳达语 高棉 老挝 拉丁语 毛利 马拉 蒙古人 尼泊尔 旁遮普 索马里 泰米尔人 泰卢固语 约鲁巴语
祖鲁
英文 Французский Немецкий Итальянский Португальский 俄文 Испанский