Загрузка среды выполнения объекта Delphi с использованием BPL

У меня класс в отряде. Обычно, когда я меняю алгоритм его методов, мне приходится его перекомпилировать и доставлять патч целиком. Думаю создать экземпляр класса с помощью DLL. После поиска на delphi.about.com я обнаружил, что вместо DLL я могу использовать BPL. Это DLL для Delphi. Проблема в том, что почти все примеры, которые я нашел, говорят только о том, как экспортировать функцию. Я хочу динамически загружать BPL, и всякий раз, когда я заменяю BPL, я могу получить последний алгоритм класса, а не только экспортируемые функции.

Статья, которую я прочитал:
- http://delphi.about.com/od/objectpascalide/a/bpl_vs_dll.htm
- Система плагинов для приложения Delphi - bpl vs dll?
- http://delphi.about.com/library/weekly/aa012301a.htm

Любой URL или ОБРАЗЕЦ, как создать BPL с нуля для инкапсуляции компонента или класса, приветствуется.


Дорогой Гуру,

Предположим, у меня есть такой код:

unit unitA;

interface

type
  B = class(TObject)
  public
    procedure HelloB;
  end;

  A = class(TObject)
  public
    function GetB: B;
    function HelloA: String;
    procedure Help;
  end;

  implementation

  uses
      Dialogs;

  { B }

   procedure B.HelloB;
   begin
     ShowMessage('B');
   end;

  { A }

  function A.GetB: B;
  begin
    Result := B.Create;
  end;

  function A.HelloA: String;
  begin
    Result := 'Hello, this is A';
  end;

  procedure A.Help;
  begin
    //do something
  end;

  end.

Я хочу экспортировать все общедоступные методы A. Как сделать это DLL? Как использовать с другого юнита, куда импортировать? скажем:

 var a: A;

 a := A.Create;
 a.GetB;
 showMessage(a.HelloA);

A не объявлен в модуле (он находится в DLL). Пожалуйста, порекомендуйте.


Ура. Получил вчера вечером. Все, что мне нужно сделать, это заставить объект реализовать интерфейс, который используется в вызывающем модуле для перехвата экземпляра объекта, возвращаемого DLL.

Спасибо вам всем.


person WishKnew    schedule 09.11.2009    source источник
comment
Ребят, а разве BPL можно сравнить с Java Class Loader? Есть ли в Delphi какая-либо функция, которая работает аналогично загрузчику классов в Java?   -  person WishKnew    schedule 12.11.2009
comment
@WishKnew: Вкратце, BPL - это DLL с дополнительными функциями. эти дополнительные функции помогают обмениваться ресурсами, такими как объекты и зависимости.   -  person Cesar Romero    schedule 13.11.2009


Ответы (6)


Проблема с помещением класса во внешний файл заключается в том, что ваше основное приложение должно знать, как на него ссылаться. Он должен будет либо происходить от базового класса, который предоставляет все необходимые вам методы как виртуальные методы, либо реализовать интерфейс, содержащий все необходимые вам функции.

Если вы уже знаете, как должен выглядеть интерфейс объекта, и все, что вы меняете, это детали реализации, такие как внутренние алгоритмы, вероятно, самым простым было бы заставить ваш класс реализовать интерфейс и поместить его в DLL, которая экспортирует функция, которая возвращает экземпляр этого интерфейса. Таким образом, вам не нужно беспокоиться о том, чтобы разбить приложение на пакеты, что может стать настоящей проблемой.

person Mason Wheeler    schedule 09.11.2009
comment
Хорошо .. Мне еще нужно прочитать про DLL. Я думал, что DLL инкапсулирует только процедуры / функции, а не объект. Я не знаю, может ли он вернуть потомок TObject или экземпляр интерфейса. Да, в моем случае прямо сейчас интерфейс никогда не будет изменен. На самом деле это калькулятор с множеством функций. Я начал с небольшого количества функций, а теперь он становится все более и более функциональным. Он просто вызвал Evaluate (выражение: String) и вернул результат в String. Когда выражение становится богаче, я не хочу заменять exe, а просто хочу заменить класс Calculator. Tq - person WishKnew; 10.11.2009

Мейсон уже это понял, но позвольте мне пояснить, почему BPL - не то, что вам нужно. BPL - это средство, с помощью которого среда Delphi IDE загружает компоненты, которые используют один и тот же диспетчер памяти и RTL. (Идентификация типа работает почти прозрачно с использованием BPL)

Однако зависимости, в которые вы попадаете, почти всегда неприемлемы. За исключением IDE, которая в любом случае не может обрабатывать разные версии RTL и VCL.

Когда вы передаете только ссылки на интерфейсы между вашим приложением и его библиотеками DLL, вам вообще не нужно совместно использовать RTL, VCL или общие пакеты.

Это также означает, что вы можете написать некоторые библиотеки DLL на другом языке (C ++, C #, FPC, другую версию Delphi) и по-прежнему использовать объекты. Что может показаться заманчивым, если вы не хотите переносить основное приложение, но все же хотите использовать существующие библиотеки, которые недоступны для Delphi или вашей версии Delphi.

person Robert Giesecke    schedule 10.11.2009
comment
Хорошо, теперь я осмелюсь разобраться, как это сделать с помощью DLL. Tq. Но как насчет COM? Есть ли у вас какие-либо комментарии, как решить проблему с помощью подхода COM? - person WishKnew; 10.11.2009
comment
COM - это совершенно другое животное, и хотя COM через Delphi значительно упрощен, он по-прежнему выходит за рамки потока stackoverflow. - person Robert Giesecke; 11.11.2009

Я не вижу в описании вашей проблемы ничего, говорящего о том, что вам нужно будет явно экспортировать что-либо из пакета или что вам нужно будет загружать его динамически во время выполнения. Вместо этого достаточно, чтобы ваши функции находились в пакете времени выполнения, который можно заменить отдельно от основной программы.

Начните новый проект пакета и переместите модуль вашего класса в этот проект вместе с любыми другими модулями, от которых он зависит. Скомпилируйте проект. Если компилятор предупреждает о «неявном включении» любых других модулей, добавьте их также в пакет.

Теперь удалите любой из модулей пакета из проекта EXE. Не должно быть единиц, которые являются участниками обоих проектов. Затем включите флажок «сборка с пакетами времени выполнения» в параметрах проекта EXE. Добавьте свой пакет в список имен пакетов, разделенных точкой с запятой. Пакеты RTL и VCL, вероятно, также будут в этом списке.

Скомпилируйте оба проекта, и все готово.

Если вы внесете изменения в реализацию своего класса, вы сможете только перекомпилировать пакет и отправить клиентам новую версию. Программа автоматически получит новые изменения, когда вы замените исходный файл новым. Пакет указан в таблице импорта программы, поэтому ОС автоматически загрузит файл BPL при загрузке EXE. EXE не нужно запускать какой-либо специальный код для загрузки пакета.

person Rob Kennedy    schedule 09.11.2009
comment
Хорошо, попробую и BPL, и DLL. Спасибо! - person WishKnew; 10.11.2009
comment
@ Роб: Я пытаюсь это сделать, но это не работает. Я разместил вопрос как раз перед тем, как найти здесь ваше сообщение. См .: stackoverflow.com/questions / 17012217 / - person Eric; 09.06.2013

Delphi может создавать DLL для экспорта функций или BPL для экспорта компонентов.

Вы можете создать компонент, скомпилировать его (используйте те же настройки компилятора, что и в вашем основном приложении), и Delphi создаст .bpl. Затем импортируйте этот компонент в Delphi и скомпилируйте приложение с этим компонентом в виде пакета.

Мой опыт работы с компонентами, созданными с помощью Delphi 4, доказал, что одно большое приложение более надежно, чем приложение с отдельными .bpls. Это был многопоточный сервер, и он отлично работал, если был скомпилирован автономно, и вылетал через короткое время, если был скомпилирован с пакетами. Я надеюсь, что новые версии Delphi улучшились в этой области.

Помните об управлении памятью (в приложении не освобождайте память, выделенную в пакете, и наоборот) и настройках компилятора.

Если вам нравится about.com, то эта ссылка будет полезна: Введение в пакеты; BPL - это особые библиотеки DLL!

person Michał Niklas    schedule 09.11.2009
comment
Если вы играете по правилам и используете один и тот же диспетчер памяти для приложений и BPL, не должно быть проблем с освобождением памяти в другом модуле, отличном от того, в котором она была выделена. Если вы не играли по этим правилам, я не удивлюсь, что ваше монолитное приложение оказалось более стабильным. Однако ваш опыт ничего не доказывает отсутствие надежности. Для этого вам сначала нужно будет доказать, что вы не ошиблись. - person mghie; 09.11.2009
comment
Я знаю об управлении памятью и предупреждал создателей / пользователей компонентов использовать одни и те же менеджеры памяти и одни и те же параметры компилятора как в компонентах, так и в приложениях. В моем случае я использовал тот же диспетчер памяти. BPL отлично работал в однопоточных приложениях, но я обнаружил загадочные сбои в многопоточных приложениях. Они появлялись через какое-то время (иногда через 15 минут, иногда через час). Они исчезли, когда я скомпилировал серверное приложение без пакетов. Это было время Delphi 4, так что теперь это доисторическое время. - person Michał Niklas; 09.11.2009

У BPL есть свое применение. Например, если вам нужно создать очень большое приложение, такое как Erp, вам нужно серьезно попробовать использовать BPL.

С другой стороны, BPL не несут ответственности за сбой приложений. Плохое использование BPL делает это.

person Francis Lee    schedule 09.11.2009
comment
BPL представляют собой худший вид ада управления версиями. Вы зависите не только от вашего компилятора и версии RTL / VCL, нет, но и от версии каждого DCU во всех общих пакетах. Для такого типа использования общего кода, о котором вы говорите, библиотеки DLL, которые совместно используют объекты через интерфейсы), являются наиболее стабильными, совместимыми (нет необходимости писать DLL в Delphi, может быть C #, C ++, FPC и т. Д.) И безболезненный путь , кроме монолитных бывших. - person Robert Giesecke; 10.11.2009

вы можете попробовать компоненты MAF, они обрабатывают плагины и многое другое без лишнего кода. Поставляется с учебными пособиями и демонстрационным приложением с исходным кодом.

http://www.maf-components.com

person Helge Lange    schedule 26.11.2009
comment
Извините, я ищу нативное решение, без использования каких-либо других платных решений. В любом случае, спасибо. - person WishKnew; 04.12.2009
comment
Похоже, что компоненты MAF - это каппут, больше никакой видимости. Они вышли из бизнеса? - person menjaraz; 21.01.2015