|
Вопрос # 3 406/ вопрос открыт / |
|
Здравствуйте!
Проблема такова. Есть класс для работы с деревом (написан мной, работает на 100%). Вот сам класс (в приложении).
Когда класс используется другим модулем (создающим дерево и работающим с ним) - все нормально, никаких багов. Мне же нужно закинуть этот класс в DLL. Решил сделать следующим образом: все процедуры - в dll, в стороннем модуле импорт подпрограмм из dll и работу с ними (в принципе, то же самое).
Когда пытаюсь вывести информацию об элементе дерева в ListView возникает ошибка 'Invalid class typecast' при этом работа программы обрывается, когда на строчке
... Node.Components[i] ... (где Node: TTreeBranch)
причем если брать отдельный элемент, то подпрограммы, написанные в dll работают как надо.
Подскажите, в чем может быть проблема.
P.S. про TreeView и про то что у него есть свои методы работы с деревом писать не надо, я это и так знаю. Спасибо :)
Приложение: Переключить в обычный режим- TTreeBranch = class
- private
- NodeCaption: string;
- NodeIndex: integer;
- NodeComponents: TObjectList;
- NodeParent: TTreeBranch;
- NodePopulation: TInfo;
- NodeTerritory: TInfo;
- NodeCities: TInfo;
- NodeCountries: TInfo;
- function GetComponent(ind: integer): TTreeBranch;
- function GetCount: integer;
- public
- property Caption: string read NodeCaption write NodeCaption;
- property Parent: TTreeBranch read NodeParent write NodeParent;
- property Index: integer read NodeIndex write NodeIndex;
- property Population: TInfo read NodePopulation write NodePopulation;
- property Territory: TInfo read NodeTerritory write NodeTerritory;
- property Cities: TInfo read NodeCities write NodeCities;
- property Countries: TInfo read NodeCountries write NodeCountries;
-
- constructor Create;
- procedure Destroy;
- procedure SetIndexes(var ind: integer);
- procedure AddNode(Node: TTreeBranch);
- procedure ShowComponents(TreeView: TTreeView; ind: integer);
- function FindByIndex(ind: integer): TTreeBranch;
- function Delete(Node: TTreeBranch): TTreeBranch;
- procedure AddMoved(NodeParent, Node: TTreeBranch);
- procedure SaveToStream(Stream: TStream);
- procedure LoadFromStream(Stream: TStream);
- procedure ShowDetails(ListView: TListView; ind: integer);
- property Components[Ind: integer]: TTreeBranch read GetComponent;
- property CountComponents: integer read GetCount;
- end;
 |
Вопрос задал: 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 (статус: Посетитель), 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-объектов.
|
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|