Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2002.07.29;
Скачать: CL | DM;

Вниз

Работа с 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;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.016 c
1-95428
Otehr_Gray
2002-07-15 11:45
2002.07.29
Вместо Delphi - два окошка


1-95357
Alex SV
2002-07-18 10:44
2002.07.29
Как работать с принтером


1-95328
lensky
2002-07-16 13:59
2002.07.29
as i nasledovanie formy ili drugoi put ?


3-95203
alexvan
2002-07-06 16:57
2002.07.29
Как в SQL запрос вставить переменную


3-95240
zombi_71
2002-07-08 11:57
2002.07.29
команда Unix