Файл BPL требует пакетов времени выполнения! - PullRequest
0 голосов
/ 17 ноября 2010

Я создал пакет и хочу использовать BPL-файл моего пакета ...

В моем пакете VCL.dcp и RTL.dcp в качестве Обязательных библиотек, я загружаю этот пакет в свое приложение безлюбые ошибки, но когда я хочу выгрузить его, показывается нарушение прав доступа!

Если я создаю свое приложение с помощью пакетов времени выполнения («vcl» и «rtl»), нарушение прав доступа не отображается!1006 *alt text

Что это значит ?!Моему приложению нужны библиотеки VCL и RTL для загрузки BPL ?!Я хочу загрузить свой пакет как файл DLL, есть ли какое-нибудь решение?

Я использую Delphi 2010

спасибо большое ...

Ответы [ 5 ]

8 голосов
/ 17 ноября 2010

Для вашего BPL требуются пакеты RTL и VCL.Если ваше приложение не требует их, то это означает, что модули RTL и VCL скомпилированы в ваш EXE-файл.Когда ваш EXE-файл загружает ваш BPL, у вас теперь есть две копии блоков RTL и VCL - один набор копий поступает из EXE-файла, а вторые копии приходят из пакетов RTL и VCL, которые ваш пакет неявно подразумевает.вызывает загрузку.

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

Я вижу три варианта для вас:

  1. Скомпилируйте ваш EXE-файл для использованияпакеты.В частности, он должен требовать тех же пакетов RTL и VCL, которые требуются вашему BPL.

  2. Сделайте так, чтобы ваш BPL не требовал каких-либо других пакетов.Если для этого не требуются RTL и VCL, то любые модули RTL и VCL, используемые вашим пакетом, будут скомпилированы в ваш BPL.Вы снова получите две отдельные копии, но они должны работать лучше, поскольку ни одна из них не подумает, что она должна быть разделена.

  3. Загружайте ваш пакет как настоящую DLL, а не какпакет.Вы сказали, что хотите использовать его как DLL, так что сделайте это.Используйте LoadLibrary, а затем GetProcAddress, чтобы получить любые функции, которые вы хотите вызвать.Если вы пойдете по этому пути, вероятно, лучше вообще не делать ваш код пакетом.Сделайте это DLL и экспортируйте функции, которые используют только те типы параметров, которые вы ожидаете найти в других DLL, такие как целые числа, указатели символов и указатели записей, а не строки или объекты.

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

1 голос
/ 17 ноября 2010

Спасибо за помощь ...

Я поместил пример своего пакета и моего Приложения здесь, чтобы найти, в чем проблема!

У нас есть пакет, не требующий пакетов времени выполнения, таких как VCL и RTL, другими словами, я удалил все библиотеки из раздела Требуется в моем пакете: alt text

мой пакет содержит форму с кодом ниже:

unit MyUnit;

interface

uses
  Windows, Forms, StdCtrls, Buttons, Controls, Classes, Dialogs;

type
  TMyForm = class(TForm)
    MyLabel: TLabel;
    MyEdit: TEdit;
    PostBtn: TBitBtn;
    procedure PostBtnClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  MyForm: TMyForm;

implementation

{$R *.dfm}

function ShowForm(FCaption, LCaption : String) : String;
var
 F : TMyForm;
begin
 F := TMyForm.Create(nil);
 try
  F.Caption := FCaption;
  F.MyLabel.Caption := LCaption;
  F.ShowModal;
 finally
  Result := F.MyEdit.Text;
  F.Free;
 end;
end;

procedure TMyForm.PostBtnClick(Sender: TObject);
begin
 if MyEdit.Text <> '' then
  Close
 else
  ShowMessage('Please Enter Value !');
end;

exports
 ShowForm;

end.

Я загружаю этот пакет и вызываю функцию ShowForm, а затем выгружаю пакет:

var
 ShowF : function(FCaption, LCaption : String) :  String;
 MyPkg : HMODULE;
 FC, LC : String;
begin
 MyPkg := LoadPackage(ExtractFilePath(Application.ExeName)+'MyPackage.bpl');
 FC := 'Enter Value ... ';
 LC := 'Value : ';
 if MyPkg <> 0 then
  begin
   try
    @ShowF := GetProcAddress(MyPkg, 'ShowForm');
    if Assigned(ShowF) then
     Edit1.Text := ShowF(FC, LC)
    else
     ShowMessage('Function not found !');
   finally
    UnloadPackage(MyPkg);
   end;
  end;
end;

После описанной выше процедуры сделано , AV показывает!

@ Neftalí: Если я просто загружаю и выгружаю Пакет, AV-шоу не выполняется, но я думаю, это потому, что я не вызываю некоторые подпрограммы или объекты или ... что им нужны библиотеки VCL или RTL, если я использую объекты и функции и ... этого пакета, после их использования я получу AV ... это правда?!

Если я создаю свое приложение с пакетом времени выполнения (VCL и RTL), AV не будет отображаться!

Я путаюсь !! Я хочу использовать пакет BPL без какого-либо пакета времени выполнения ...

спасибо большое ...

1 голос
/ 17 ноября 2010

Что у вас внутри пакета?
Какую работу вы с ним делаете?
Как вы заряжаете и разряжаете?Что в нем?

Что вы делаете с пакетом перед его выгрузкой?
Когда вы выгружаете его, все объекты / формы / компоненты / ..., которые вы использовали, освобождаются?

ДОБАВЛЕНО: Я думаю, что вы используете что-либо из пакета, когда пытаетесь загрузить.Это является причиной AV.

В EXE-файл, скомпилированный без пакета времени выполнения, я загружаю пакет:

  OutputDebugString(PChar('Loading the package'));
  hand := LoadPackage('r:\rrrrrrr\Package1.bpl');

Я выгружаю пакет с этим кодом:

  OutputDebugString(PChar('Ready to Unload Package'));
  UnloadPackage(hand);
  OutputDebugString(PChar('Unloaded'));

В пакете есть блок с формой ( form1 ) и блок Init.pas для инициализации, подобной этой:

unit Init;

interface

// prototipos
procedure Start_P;
procedure Finish_P;

implementation

uses
  Unit1, Windows;

procedure Finish_P();
begin
  OutputDebugString(PChar('Finish_P   form free'));
  Form1.Free;
end;


procedure Start_P();
begin
  OutputDebugString(PChar('Start_P   Creating form'));
  Form1 := TForm1.Create(nil);
  Form1.Show;
end;

Initialization;
  Start_P();

Finalization;
  Finish_P();

end.

Пакет загружается и форма визуализируется без проблем, так же как и с операциями Close и Unload.Проект скомпилирован с «Build with rutime пакетами» unchecked .

Можете выложить любой код.

Результат OutputDebugString таков (без ошибки AV):

[2644] Загрузка пакета
[2644] Start_P Создание формы
[2644] Готов кВыгрузить пакет
[2644] Готово Finish_P бесплатно
[2644] выгружено

С уважением.

0 голосов
/ 18 ноября 2010

Ооооо, отличный надзор / пренебрежение (мой).
С помощью кода, который вы разместили, просто измените его тест (используйте PChar).

function ShowForm(FCaption, LCaption : String) : PChar;  
...

    Result := PChar(F.MyEdit.Text);
  ...

То же самое, когда вы определяете ситаксис функции:

 ShowF : function(FCaption, LCaption : String):PChar;

Проверьте это и произнесите результат.

С уважением.

0 голосов
/ 17 ноября 2010

Да, если вы хотите использовать пакеты времени выполнения в своем приложении, вам нужно собрать его с пакетами времени выполнения, а затем он требует их (ссылки статически с ними). ​​

Решение вашей проблемы зависит от того, чтопроблема на самом деле есть (что пока неясно).

...