Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 23.07.2009, 20:03   #11
0nni
Форумчанин
 
Аватар для 0nni
 
Регистрация: 24.07.2008
Сообщений: 279
По умолчанию

Потому что такие фокусы с классами в dll не работают. Тебе же дали ссылку на статью в КД, ты ее читал?
Сказал и загрустил от бесспорности своей правоты.
0nni вне форума Ответить с цитированием
Старый 23.07.2009, 20:45   #12
Daramant
Форумчанин
 
Регистрация: 06.01.2009
Сообщений: 340
По умолчанию

Цитата:
Но вопрос по-прежнему остаётся.
Почему
Я же дал ссылку (прочти все внимательно):
http://www.delphikingdom.com/asp/ans...IDAnswer=68178

Поможет вот это:
Код:
someDLLComboBox.items.Clear();
someDLLComboBox.items.AddStrings(someDLLList);
Истинный успех – это то, что Вы сделали в сравнении с тем, что могли бы сделать.
Никогда не бойся делать то, что ты не умеешь. Помни, ковчег был построен любителем. Профессионалы построили "Титаник".
Daramant вне форума Ответить с цитированием
Старый 23.07.2009, 20:57   #13
Altera
Старожил
 
Аватар для Altera
 
Регистрация: 29.01.2008
Сообщений: 2,406
По умолчанию

Цитата:
Сообщение от Daramant Посмотреть сообщение
Я же дал ссылку (прочти все внимательно):
http://www.delphikingdom.com/asp/ans...IDAnswer=68178

Поможет вот это:
Код:
someDLLComboBox.items.Clear();
someDLLComboBox.items.AddStrings(someDLLList);
Да, помочь то помогло
Код:
someDLLComboBox.items.Clear();
someDLLComboBox.items.AddStrings(someDLLList);
и http://www.delphikingdom.com/asp/ans...IDAnswer=68178 тоже прочитал. Но я так и не понял, почему
Код:
someDLLComboBox.items.assign(someDLLList);
не работает

Один чувак сказал, что надо shareMem, я поставил его в dpr-ках dll и exe gthdsv модулем в uses, только толку я не замечаю с него
Altera вне форума Ответить с цитированием
Старый 24.07.2009, 12:27   #14
Daramant
Форумчанин
 
Регистрация: 06.01.2009
Сообщений: 340
По умолчанию

Цитата:
Один чувак сказал, что надо shareMem, я поставил его в dpr-ках dll и exe gthdsv модулем в uses, только толку я не замечаю с него
shareMem в данном случае не поможет. shareMem содержит менеджер памяти, общий для exe-программы и dll. Он позволяет корректно работать с динамически выделяемыми блоками памяти, когда выделение блока произошло в коде exe-программы, а освободить его требуется в dll или наоборот. (Например, работа со строками.)
Если интересно, подробнее можно прочитать здесь:

http://www.cyberguru.ru/programming/...ils-page8.html

Цитата:
и http://www.delphikingdom.com/asp/ans...IDAnswer=68178 тоже прочитал. Но я так и не понял, почему
Код:
someDLLComboBox.items.assign(someDL LList);
не работает
Дело в том, что при использовании метода assign, в его теле происходит проверка типов run-time (во время исполнения), операцией is
Код:
if Source is TStrings then
а при вызове метода AddStrings, только на этапе компиляции.

Как определяется тип?
Разберемся, как работает механизм определения принадлежности объекта (Obj) к заданному классу (AClass).
В любом объекте есть указатель на VMT (таблица виртуальных методов).
В этой таблице есть указатель на класс к которому пренадлежит данный объект (vmtSelfPtr) и указатель на класс предок (vmtParent).
Т.е. если указатель vmtSelfPtr равен указателю AClass, это значит что объект является экземпляром класс AClass.
Если один из указателей vmtParent (текущего класса, класса потомка и т.д.) равен указателю AClass, это значит, что класс объекта является потомком класса AClass.

Почему же типы различны?
Разберемся, что происходит при запуске программы.
В сегмент данных загружается информация об используемых в программе типах (классах, их потомках и прочее).
В нашем случае есть участок памяти в котором хранится информация о классе TStringList. (TStringList по сути есть указатель на этот участок памяти)
При загрузке dll в ней тоже описаны типы (классы и прочее), они загружаются в свой сегмент данных, т.е. dll будет содержать свой участок памяти в котором описан класс TStringList.
Получается, что мы имеем два участка памяти, содержащих одно и тоже описание класса TStringList. По сути TStringList из exe и TStringList из dll это одно и тоже (копии), но формально, если сравнить указатели на классы и проследить потомков – это разные классы, имеющие каждый свою иерархию наследования.

Поэтому и вылетает исплючение.

Теперь по коду, при вызове:
Код:
someDLLComboBox.items.assign(someDLLList);
Тело метода:
Код:
procedure TStrings.Assign(Source: TPersistent);
begin
  if Source is TStrings then // проверка дает результат false
  begin
    BeginUpdate;
    try
      Clear;
      FDefined := TStrings(Source).FDefined;
      FNameValueSeparator := TStrings(Source).FNameValueSeparator;
      FQuoteChar := TStrings(Source).FQuoteChar;
      FDelimiter := TStrings(Source).FDelimiter;
      AddStrings(TStrings(Source));
    finally
      EndUpdate;
    end;
    Exit;
  end;
  inherited Assign(Source); // вызывается метод предка
end;

// А именно метод Assign класса TPersistent
procedure TPersistent.Assign(Source: TPersistent);
begin
  if Source <> nil then Source.AssignTo(Self) else AssignError(nil);
end;

// Далее 
procedure TPersistent.AssignTo(Dest: TPersistent);
begin
  Dest.AssignError(Self);
end;

// а AssignError и дает исключение.
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;

P.S.
Как же все таки заставить данный код работать?
Теоретически все просто. Если создавать все объекты в одном месте, допустим в dll (или в exe), то они будут иметь единую иерархию наследования, и все будет работать.
Например, можно создать ComboBox в exe-файле, затем передать его в dll и разместить на форме, в таком случае, данный код будет работать т.к. TStringList был создан так же в exe-файле.
Но, на практике не все так просто. Потребуется существенное переписывание программы, некоторые элементы возможно вообще не получится переделать.
Истинный успех – это то, что Вы сделали в сравнении с тем, что могли бы сделать.
Никогда не бойся делать то, что ты не умеешь. Помни, ковчег был построен любителем. Профессионалы построили "Титаник".
Daramant вне форума Ответить с цитированием
Старый 24.07.2009, 16:58   #15
0nni
Форумчанин
 
Аватар для 0nni
 
Регистрация: 24.07.2008
Сообщений: 279
По умолчанию

В случаях с Combobox, ListBox все банально решается через SendMessage();
Сказал и загрустил от бесспорности своей правоты.
0nni вне форума Ответить с цитированием
Старый 24.07.2009, 20:23   #16
lexaltd
Форумчанин
 
Регистрация: 21.07.2008
Сообщений: 192
По умолчанию

Цитата:
Сообщение от 0nni Посмотреть сообщение
В случаях с Combobox, ListBox все банально решается через SendMessage();
Можно пример?
А с TCheckListBox можно , мне нужно узнать какие пункты выделены галками?
lexaltd вне форума Ответить с цитированием
Старый 24.07.2009, 22:08   #17
0nni
Форумчанин
 
Аватар для 0nni
 
Регистрация: 24.07.2008
Сообщений: 279
По умолчанию

Цитата:
Сообщение от lexaltd Посмотреть сообщение
Можно пример?
Почитать первую строку:
Код:
var
  buff : Pointer;
  ItemLength : Integer;
begin
  ItemLength := SendMessage(hListBox, LB_GETTEXTLEN,0, 0);
  buff := GetMemory(ItemLength + 1);
  ZeroMemory(buff, ItemLength + 1);
  SendMessage(hListBox, LB_GETTEXT, 0, Integer(buff));
  Caption := Pchar(buff);
  FreeMem(buff, ItemLength + 1);
Цитата:
Сообщение от lexaltd Посмотреть сообщение
А с TCheckListBox можно , мне нужно узнать какие пункты выделены галками?
Про TCheckListBox не помню, есть ли для него сообщения. Но в любом случае можно "научить" его своим.
Сказал и загрустил от бесспорности своей правоты.

Последний раз редактировалось 0nni; 24.07.2009 в 22:11.
0nni вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Ошибка при компиляции MasterofCDM Общие вопросы Delphi 2 11.11.2008 09:35
Ошибка при отключении ОС GREK Операционные системы общие вопросы 1 24.09.2008 16:50
Ошибка при удалении... JRcoker Общие вопросы Delphi 8 29.07.2008 22:53
Ошибка при присваивании NeiL Общие вопросы Delphi 5 16.04.2008 22:24
Ошибка при компиляции zak Общие вопросы C/C++ 2 11.12.2007 18:24