1

パッケージを作成しました。パッケージの BPL ファイルを使用したいのですが...

私のパッケージには必須ライブラリとして VCL.dcp と RTL.dcp があります。このパッケージをアプリケーションにロードしてもエラーは発生しませんが、アンロードしようとすると、アクセス違反が表示されます。

ランタイム パッケージ ("vcl" および "rtl") を使用してアプリケーションをビルドすると、アクセス違反が表示されません。

代替テキスト

これはどういう意味です ?!私のアプリケーションは、BPL をロードするために VCL と RTL ライブラリが必要ですか?! パッケージを DLL ファイルのようにロードしたいのですが、解決策はありますか?

Delphi 2010 を使用しています

どうもありがとう ...

4

5 に答える 5

8

BPL には RTL および VCL パッケージが必要です。アプリケーションがそれらを必要としない場合は、RTL および VCL ユニットが EXE ファイルにコンパイルされていることを意味します。EXE が BPL をロードすると、RTL ユニットと VCL ユニットの2 つのコピーが作成されます。1 組のコピーは EXE 内から取得され、2 番目のコピーは、パッケージによって暗黙的に読み込まれる RTL および VCL パッケージから取得されます。

Delphi は、そのような状況に対応することを意図していません。ある RTL によって割り当てられ、他の RTL によって解放されようとしたメモリがある可能性があります。または、VCL パッケージにあった関数を参照する関数ポインタが EXE にある可能性があります。

次の 3 つのオプションがあります。

  1. パッケージを使用するには、EXE をコンパイルします。具体的には、BPL が必要とするのと同じ RTL および VCL パッケージが必要です。

  2. BPLに他のパッケージを必要としないようにしますRTL と VCL を必要としない場合、パッケージが使用する RTL と VCL ユニットはすべて BPL にコンパイルされます。再び 2 つの別々のコピーが作成されることになりますが、どちらのコピーも共有されているとは思わないため、より適切に機能するはずです。

  3. パッケージのようにではなく、実際の DLL のようにパッケージをロードします。あなたはそれをDLLのように使いたいと言ったので、そうしてください。を使用してLoadLibraryから、 を使用GetProcAddressして、呼び出したい関数を取得します。この方法をとる場合は、コードをまったくパッケージにしない方がよいでしょう。それを DLL にして、文字列やオブジェクトではなく、整数、文字ポインター、レコード ポインターなど、他の DLL にあると予想されるパラメーター型のみを使用する関数をエクスポートします。

最初のオプションが最も簡単であることは明らかです。2 番目の方法はおそらく機能する可能性があり、それはあなたが好む方法のように思えますが、最終的に機能する前に、より多くの頭痛の種が生成されると思います. このプロジェクトの存続期間中に他の開発環境を使用する必要がある場合は、3 番目のオプションが最適です。

于 2010-11-17T15:52:18.170 に答える
1

パッケージの中身は?
それを使ってどんな仕事をしますか?
充電と放電はどのように行うのですか?何が入ってるの?

アンロードする前にパッケージをどうしますか?
アンロードすると、使用したすべてのオブジェクト/フォーム/コンポーネント/...が解放されますか?

追加: オンロードしようとすると、パッケージの何かを使用していると思います。これが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 の操作も同様です。プロジェクトは、「Rutime パッケージでビルド」のチェックを外してコンパイルされます。

コードを投稿できますか。

OutputDebugString の結果は次のとおりです (AV エラーなし)。

[2644] パッケージの読み込み中
[2644] Start_P フォームの作成
[2644] パッケージのアンロード準備
完了 [2644] Finish_P フォームの解放
[2644 ] アンロード済み

よろしく。

于 2010-11-17T15:59:20.383 に答える
1

助けてくれてありがとう...

問題の原因を見つけるために、ここにパッケージとアプリケーションの例を示します。

VCL や RTL などのランタイム パッケージを必要としないパッケージがあります。つまり、パッケージの Requires セクションからすべてのライブラリを削除しました。 代替テキスト

私のパッケージには、以下のコードを含むフォームが含まれています:

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í : Package のロードとアンロードを行うだけの場合、AV Shows はありませんが、オブジェクトと関数を使用する場合、いくつかのルーチンやオブジェクトを呼び出さないか、VCL または RTL Libraries が必要なためだと思いますそして...このパッケージの、それらを使用した後、私はAVを取得します...それは本当ですか?!

ランタイム パッケージ (VCL および RTL) を使用してアプリケーションをビルドすると、AV が表示されません。

紛らわしいです!! 、Run-Timeパッケージを必要としないBPLパッケージを使用したい...

どうもありがとう ...

于 2010-11-17T17:03:17.033 に答える
0

はい、アプリケーションでランタイム パッケージを使用する場合は、ランタイム パッケージを使用してビルドする必要があります。その後、ランタイム パッケージが必要になります (静的にリンクします)。

問題の解決策は、問題が実際に何であるかによって異なります (現時点では不明です)。

于 2010-11-17T15:29:06.360 に答える
0

ああ、大きな見落とし/怠慢(私のもの)。
投稿したコードを使用して、簡単な変更を加えてテストしました (PChar を使用)。

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

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

関数の sitaxis を定義する場合も同じです。

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

それをテストし、結果を言います。

よろしく。

于 2010-11-18T10:30:11.170 に答える