Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Приведение типов объектов в DLL, (замысловатая ку-ку) 
:(
    Опции темы
790
Дата 30.5.2006, 23:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 25.5.2006

Репутация: нет
Всего: нет



Всем ку!
Появилась неожиданная проблема.
Есть куча классов, наследуемых от TBaseClass
например: 
TRaspred = class(TBaseClass)
В приложении создаются экземпляры этих классов, заполняются данными, все дела. 
Потом передаются ф-ии из Dll:
Код

fnDAMain(ptrPS:PPS)
,
где 
Код

PPS = ^TPS 
(TPS тож наследуется от TBaseClass)
в DLL в fnDAMain есть такой код:

Код

iIkCnt: integer;
ptrPS: PPS; 
ptrRU: PBASECLASS; //PBASECLASS = ^TBaseClass
...
ptrRU := ptrPS^.GetListObject(i);

{возвращает PBASECLASS. Но по факту указывает на объект класса TRaspred,
и потом}

Код

iIkCnt := (ptrRU^ as TRaspred).GetListCount(2);

На этой строке появляется имсключение EInvalidCast с матом: Invalid type cast.
Хотя! Если эту fnDAMain(ptrPS:PPS) вызывать не через DLL, а просто скомпилить в приложение, то все пучком. 
Смотрел адреса, куда указатели показывают. В приложении и DLL они совпадают.
DLL подключал и явно и неявно. По-барабану. Та же ошибка.
Что это может быть и как это исправить или обойти? 
PM MAIL   Вверх
Romikgy
Дата 31.5.2006, 08:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

Репутация: 26
Всего: 146



Код

    
iIkCnt := TRaspred(ptrRU^).GetListCount(2);

А так если? 


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Snowy
Дата 31.5.2006, 09:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 192
Всего: 484



Ты хочешь передавать объекты в dll?
А где описан TBaseClass? И как ты создаешь наследника от него в dll?
Не, так не пойдет. Если dll - юзай интерфейсы.
А лучше юзай bpl. Там всё необходимое уже предусмотрено. 
PM MAIL   Вверх
790
Дата 31.5.2006, 20:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 25.5.2006

Репутация: нет
Всего: нет



Цитата(Snowy @  31.5.2006,  09:40 Найти цитируемый пост)
Ты хочешь передавать объекты в dll?
А где описан TBaseClass? И как ты создаешь наследника от него в dll?

Не объект, а указатель на него. И в DLL работаю с указателями. TBaseClass описан в юните, кот-ый подключается как при компиляции приложения, так и при сборке dll.
Наследник от него создается как
Код

ptrRU: PBASECLASS;
...
{потом надо присвоит этому указателю ссылку на объект (кот-ый на самом деле типа TRaspred, просто ф-ия класс TPS возвращает ука-ль на баз. класс}
ptrRU := ptrPS^.GetListObject(i);
{и получить одно из полей этого объекта класса TRaspred, приведя указ-ль ptrPS к этому типу. Напомню, что TRaspred = class(TBaseClass)}
iIkCnt := (ptrRU^ as TRaspred).GetListCount(2);
//мат: Invalid type cast. И только в dll


Пользовать интерфейсы и bpl нельзя, т.к. то приложение, кот-ое должно хорошо работать с этой dll, делелось моим начальником неск. месяцев и сдавать проект уже скоро. Если я ему предложу bpl и интерфейсы, он мне ничего хорошего не предложит в ответ  smile . Если серьезно, то уже нет времени разбираться в bpl и интерфейсах.
Мне недавно подсказали, что стоит использовать какое-то ShareMem.
Есть ли еще идеи, что делать?
 
PM MAIL   Вверх
Snowy
Дата 1.6.2006, 08:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 192
Всего: 484



Не получится так.
TBaseClass в exe и TBaseClass в dll, в откомпиленом варианте это совсем разные классы.
Ни о каком приведении и речи быть не может.
Никакой шаремем тут не поможет.
Либо интерфейсы, либо bpl. 
bpl не мешает использовать dll. По сути bpl - это dll с расширенными возможностями. 
PM MAIL   Вверх
790
Дата 1.6.2006, 22:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 25.5.2006

Репутация: нет
Всего: нет



Цитата(Snowy @  1.6.2006,  08:57 Найти цитируемый пост)
TBaseClass в exe и TBaseClass в dll, в откомпиленом варианте это совсем разные классы.
Ни о каком приведении и речи быть не может.

Опа. Вот этого я и не подозревал. Спасибо за науку. Так значит bpl. Хорошо, поковаряюсь с этим.

Кстати, а как бы вы решили эту проблему по сути? Т.е. надо, чтоб dll, подключенная приложением работала с объектами (деревом объектов), созданными в приложении
 
PM MAIL   Вверх
790
Дата 1.6.2006, 23:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 25.5.2006

Репутация: нет
Всего: нет



или не dll, но что-то динамически подключаемое 
PM MAIL   Вверх
Snowy
Дата 2.6.2006, 09:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 192
Всего: 484



Если подключаемый модуль один, то я бы описание класса дал в нем.
Создание и заполнение в exe, использование в модуле.

Если модулей несколько, то создаем третью bpl, в которой описываем класс.
ехе и все подключаемые подключают этот третий модуль и используют класс.

Это все для BPL.

Если мы хотим остаться на dll, то тут другой принцип.
Объекты мы не используем. Но! Мы можем передавать данные.
Оптимально здесь подойдет сериализация.
У тебя есть одинаково описанный клас в ехе и dll. Онинаковые проперти. Все одинаково по именам.
Различаются они своим физическим местонахождением.
Значит создаем наш объект. Сериализуем его в TMemoryStream. Загоняем данные в буфер. Передаём буфер dll-ке. Уничтожаем объект.
В dll: Загоняем буфер в TMemoryStream. Создаём объект. Десериализуем объект из стрима. Используем.
Если твоё дерево наследуется от TConponent, то в нем уже зашита сериализация (SaveToStream).
Если нет, то читай мою статью про TPersistent. 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0510 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.