Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 3 406

/ вопрос открыт /

Здравствуйте!
Проблема такова. Есть класс для работы с деревом (написан мной, работает на 100%). Вот сам класс (в приложении).

Когда класс используется другим модулем (создающим дерево и работающим с ним) - все нормально, никаких багов. Мне же нужно закинуть этот класс в DLL. Решил сделать следующим образом: все процедуры - в dll, в стороннем модуле импорт подпрограмм из dll и работу с ними (в принципе, то же самое).

Когда пытаюсь вывести информацию об элементе дерева в ListView возникает ошибка 'Invalid class typecast' при этом работа программы обрывается, когда на строчке

... Node.Components[i] ... (где Node: TTreeBranch)

причем если брать отдельный элемент, то подпрограммы, написанные в dll работают как надо.

Подскажите, в чем может быть проблема.

P.S. про TreeView и про то что у него есть свои методы работы с деревом писать не надо, я это и так знаю. Спасибо :)

Приложение:
  1. TTreeBranch = class
  2. private
  3. NodeCaption: string;
  4. NodeIndex: integer;
  5. NodeComponents: TObjectList;
  6. NodeParent: TTreeBranch;
  7. NodePopulation: TInfo;
  8. NodeTerritory: TInfo;
  9. NodeCities: TInfo;
  10. NodeCountries: TInfo;
  11. function GetComponent(ind: integer): TTreeBranch;
  12. function GetCount: integer;
  13. public
  14. property Caption: string read NodeCaption write NodeCaption;
  15. property Parent: TTreeBranch read NodeParent write NodeParent;
  16. property Index: integer read NodeIndex write NodeIndex;
  17. property Population: TInfo read NodePopulation write NodePopulation;
  18. property Territory: TInfo read NodeTerritory write NodeTerritory;
  19. property Cities: TInfo read NodeCities write NodeCities;
  20. property Countries: TInfo read NodeCountries write NodeCountries;
  21.  
  22. constructor Create;
  23. procedure Destroy;
  24. procedure SetIndexes(var ind: integer);
  25. procedure AddNode(Node: TTreeBranch);
  26. procedure ShowComponents(TreeView: TTreeView; ind: integer);
  27. function FindByIndex(ind: integer): TTreeBranch;
  28. function Delete(Node: TTreeBranch): TTreeBranch;
  29. procedure AddMoved(NodeParent, Node: TTreeBranch);
  30. procedure SaveToStream(Stream: TStream);
  31. procedure LoadFromStream(Stream: TStream);
  32. procedure ShowDetails(ListView: TListView; ind: integer);
  33. property Components[Ind: integer]: TTreeBranch read GetComponent;
  34. property CountComponents: integer read GetCount;
  35. end;


Roma_no_off Вопрос ожидает решения (принимаются ответы, доступен мини-форум)

Вопрос задал: Roma_no_off (статус: Посетитель)
Вопрос отправлен: 15 ноября 2009, 21:15
Состояние вопроса: открыт, ответов: 2.

Ответ #1. Отвечает эксперт: Вадим К

Здравствуйте, Roma_no_off!
Ну почему все хотят запихнуть классы в длл? а смысл какой? никакого! Плюс длл не умеют экспортировать классы. длл умеют экспортировать только функции.
следующая проблема - класс в длл и класс в основной программе, хоть и имеют одно имя, являются разными классами (почему? всё просто, лучше делать так, чем стараться обеспечить бинарную совместимость).
Еще одна проблема - класс string. его нельзя передавать через границу dll-приложение, если не применить ShareMem.

Итого видим, что ошибок в коде просто огромное кол-во. Что же делать?
- если хочется вынести класс в длл, то надо либо применять bpl (так кстати делает делфи и там почти все проблемы решаются автоматом), либо в длл делать функции-обвязки (это может быть порой очень сложно), либо делать COM объект
- учить делфи и виндовс глубже!

Ответ отправил: Вадим К (статус: Академик)
Время отправки: 16 ноября 2009, 11:27

Ответ #2. Отвечает эксперт: DNK

Здравствуйте, Roma_no_off!

Цитата (Roma_no_off):

Мне же нужно закинуть этот класс в DLL.
Нет. Не нужно. Полностью согласен с Вадимом. Опытным путем пришел к выводу, что DLL хороши только в 2 случаях: плагины и хранение крупных и редко используемых ресурсов (чтоб ехе за зря не пух). Если же тебе нужно использовать твой класс в нескольких программах, создавай Package и устанавливай его как библиотеку в саму Delphi.

Ответ отправил: DNK (статус: Студент)
Время отправки: 16 ноября 2009, 11:56
Оценка за ответ: 5

Комментарий к оценке: Да я это прекрасно понимаю, но надо как то сделать так, чтобы деревом оперировал DLL

Мини-форум вопроса

Всего сообщений: 2; последнее сообщение — 16 ноября 2009, 09:47; участников в обсуждении: 2.
Roma_no_off

Roma_no_off (статус: Посетитель), 15 ноября 2009, 21:22 [#1]:

Прошу прощения, этот класс используется в dll, но его п\п туда не закидываются, в библиотеку закидывается следующий класс:
TOperator = class
    private
      SaveIndex: integer;
      Stream: TStream;
    public
      procedure AddRoot(TreeView: TTreeView);
      procedure AddNode(TreeView: TTreeView; index: integer);
      procedure Delete(TreeView: TTreeView);
      procedure Destroy(Node: TTreeBranch);
      procedure Edit(TreeView: TTreeView);
      procedure Move(TreeView: TTreeView; IndFrom, IndTo: integer);
      procedure SaveNode(TreeView: TTreeView);
      procedure LoadNode(TreeView: TTreeView);
      procedure ShowNodeDetails(ListView: TListView; index: integer);
  end;

ну а описание то же самое.

а это уже фрагмент кода из dll

procedure ShowNodeDetails(ListView: TListView; Node: TTreeBranch);
  var
    i: integer;
  begin
      for i:=0 to Node.CountComponents - 1 do
        with ListView.Items.Add do begin
          Caption:=IntToStr(i+2);
          SubItems.Add(Node.Components[i].Caption);
          with Node.Components[i].Population do
            SubItems.Add(FloatToStr(Value)+' '+Rate);
          with Node.Components[i].Territory do
            SubItems.Add(FloatToStr(Value)+' '+Rate);
          with Node.Components[i].Cities do
            SubItems.Add(FloatToStr(Value)+' '+Rate);
          with Node.Components[i].Countries do
            SubItems.Add(FloatToStr(Value)+' '+Rate);
        end;
    end;

Ошибка возникает при обращении к Node.Components[i]
Косолапов Дмитрий Юрьевич

Косолапов Дмитрий Юрьевич (статус: 8-ой класс), 16 ноября 2009, 09:47 [#2]:

Проверяйте приватную функцию
function GetComponent(ind: integer): TTreeBranch;
Также по прежнему непонятно, что там в DLL, а что в вызываемой программе.
Возможно, нужно думать в сторону COM-объектов.

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 16:46
Выполнено за 0.04 сек.