Форум: "Основная";
Текущий архив: 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);
begin
if Source <> nil then Source.AssignTo(Self) else AssignError(nil);
end;
procedure TPersistent.AssignError(Source: TPersistent);
var
SourceName: string;
begin
if Source <> nil then
SourceName := Source.ClassName else
SourceName := "nil";
raise EConvertError.CreateResFmt(@SAssignError, [SourceName, ClassName]);
end;
Отсюда очевидно, что 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;
begin
Result := (CompareText(PropName, "Active") = 0) or
(CompareText(PropName, "Connected") = 0) or
(CompareText(PropName, "Name") = 0)
end;
procedure CopyObject(const Source, Dest : TObject);
var
PropList: PPropList;
i, iPropCount : Integer;
begin
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));
end
end;
...
CopyObject(DLLReturnsFont, FFont);
← →
Eugene Lachinov (2002-07-16 14:10) [19]Упущен FreeMem
procedure CopyObject(const Source, Dest : TObject);
var
PropList: PPropList;
i, iPropCount : Integer;
begin
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));
end
finally
FreeMem(PropList)
end
end;
← →
Гас (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.5 MB
Время: 0.006 c